免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2103 | 回复: 1
打印 上一主题 下一主题

RUBY中保存异常现场 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-24 11:07 |只看该作者 |倒序浏览
RUBY中保存异常现场



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

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

  实例变量已经在RAILS已经有现在的实现了

引用
http://apidock.com/rails/Object/instance_values


Ruby代码
  1. 1.# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 12   
  2. 2.  def instance_values #:nodoc:   
  3. 3.    Hash[instance_variables.map { |name| [name.to_s[1..-1], instance_variable_get(name)] }]   
  4. 4.  end  
  5. # File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 12
  6.   def instance_values #:nodoc:
  7.     Hash[instance_variables.map { |name| [name.to_s[1..-1], instance_variable_get(name)] }]
  8.   end
复制代码
但没有找到local_values这个方法,好吧,我们自己来实现一个

Ruby代码
  1. 1.def local_values(context, black_list = [])   
  2. 2.  black_list.concat(%w[local_value_hashs])   
  3. 3.  context.eval <<-EOS   
  4. 4. local_value_hashs = {}   
  5. 5. local_variables.each do |var_name|   
  6. 6.   next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name   
  7. 7.   local_value_hashs[var_name] = eval(var_name)   
  8. 8. end  
  9. 9. local_value_hashs   
  10. 10.  EOS   
  11. 11.end  
  12.     def local_values(context, black_list = [])
  13.       black_list.concat(%w[local_value_hashs])
  14.       context.eval <<-EOS
  15.      local_value_hashs = {}
  16.      local_variables.each do |var_name|
  17.        next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name
  18.        local_value_hashs[var_name] = eval(var_name)
  19.      end
  20.      local_value_hashs
  21.       EOS
复制代码
end


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

小demo

Ruby代码
  1. 1.require 'pp'  
  2. 2.class Kitty   
  3. 3.  def hello   
  4. 4.    str = "hello kitty"  
  5. 5.    raise 'test kitty'  
  6. 6.  rescue   
  7. 7.    pp local_values(binding)   
  8. 8.  end  
  9. 9.  
  10. 10.  def local_values(context, black_list = [])   
  11. 11.    black_list.concat(%w[local_value_hashs])   
  12. 12.    context.eval <<-EOS   
  13. 13.     local_value_hashs = {}   
  14. 14.     local_variables.each do |var_name|   
  15. 15.       next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name   
  16. 16.       local_value_hashs[var_name] = eval(var_name)   
  17. 17.     end  
  18. 18.     local_value_hashs   
  19. 19.    EOS   
  20. 20.  end  
  21. 21.end  
  22. 22.  
  23. 23.Kitty.new.hello  
  24. require 'pp'
  25. class Kitty
  26.   def hello
  27.     str = "hello kitty"
  28.     raise 'test kitty'
  29.   rescue
  30.     pp local_values(binding)
  31.   end

  32.   def local_values(context, black_list = [])
  33.     black_list.concat(%w[local_value_hashs])
  34.     context.eval <<-EOS
  35.      local_value_hashs = {}
  36.      local_variables.each do |var_name|
  37.        next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name
  38.        local_value_hashs[var_name] = eval(var_name)
  39.      end
  40.      local_value_hashs
  41.     EOS
  42.   end
  43. end

  44. Kitty.new.hello

  45. 输出结果

  46. 引用
  47. {"str"=>"hello kitty"}
复制代码
思路

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

论坛徽章:
0
2 [报告]
发表于 2011-10-25 00:49 |只看该作者
好好好,很好啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP