- 论坛徽章:
- 0
|
RUBY中保存异常现场
无法接触到服务器,但有些问题需要异常的数据,虽然可以在抛出异常时把数据给手动打印到日记,感觉太麻烦了
记得有看豆瓣的架构时,有提到他们在发生异常时,会把当时的所有变量都打印到日记里,方便调试.
在RUBY中实现这个也不难,稍微有点难的是本地变量的保存
实例变量已经在RAILS已经有现在的实现了
引用
http://apidock.com/rails/Object/instance_values
Ruby代码- 1.# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 12
- 2. def instance_values #:nodoc:
- 3. Hash[instance_variables.map { |name| [name.to_s[1..-1], instance_variable_get(name)] }]
- 4. end
- # 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这个方法,好吧,我们自己来实现一个
Ruby代码- 1.def local_values(context, black_list = [])
- 2. black_list.concat(%w[local_value_hashs])
- 3. context.eval <<-EOS
- 4. local_value_hashs = {}
- 5. local_variables.each do |var_name|
- 6. next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name
- 7. local_value_hashs[var_name] = eval(var_name)
- 8. end
- 9. local_value_hashs
- 10. EOS
- 11.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
复制代码 end
这个方法默认只需要一个参数,context参数在发生异常的rescue语句里调用binding方法,black_list参数是一个数组,当你不需要把某些本地变量给打印出来的,把它的名字写到这个数组就行了
小demo
Ruby代码- 1.require 'pp'
- 2.class Kitty
- 3. def hello
- 4. str = "hello kitty"
- 5. raise 'test kitty'
- 6. rescue
- 7. pp local_values(binding)
- 8. end
- 9.
- 10. def local_values(context, black_list = [])
- 11. black_list.concat(%w[local_value_hashs])
- 12. context.eval <<-EOS
- 13. local_value_hashs = {}
- 14. local_variables.each do |var_name|
- 15. next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name
- 16. local_value_hashs[var_name] = eval(var_name)
- 17. end
- 18. local_value_hashs
- 19. EOS
- 20. end
- 21.end
- 22.
- 23.Kitty.new.hello
- 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
- end
- end
- Kitty.new.hello
- 输出结果
- 引用
- {"str"=>"hello kitty"}
复制代码 思路
•通过binding方法获取异常发生的上下文
•调用上下文的eval方法,在eval里通过ruby自带的local_variables,获取所有本地变量的名称
•通过eval获取本地变量的值,把它存起来,返回结果 |
|