Project1

标题: 模拟异常重抛出 Re-raise 0.02 [打印本页]

作者: 晴兰    时间: 2014-2-22 18:10
提示: 作者被禁止或删除 内容自动屏蔽
作者: 柍若    时间: 2014-2-22 19:23
{:2_258:}晴兰女神!
居然有沙发!!

咳…请问堆栈是什么意思?
作者: satgo1546    时间: 2014-2-22 19:30
有什么用途吗……
作者: 余烬之中    时间: 2014-2-22 20:51
satgo1546 发表于 2014-2-22 19:30
有什么用途吗……


大概这样用?


某插件脚本:
RUBY 代码复制
  1. # 插件模组EX
  2. module EX
  3. # ...
  4. def self.some_method *arg
  5.     # do sth
  6.     arg[2] += 1
  7.     # do sth
  8.   rescue
  9.     $ex = $!
  10.   end
  11. # ...
  12. end

RUBY 代码复制
  1. # Game_Interpreter
  2. # ...
  3.    #--------------------------------------------------------------------------
  4.   # ● 脚本
  5.   #--------------------------------------------------------------------------
  6.   alias :old_cmd355 :command_355
  7.   def command_355
  8.     old_cmd355
  9.     reraise $ex if $ex
  10.     $ex = nil
  11.   end
  12. # ...

某事件脚本
RUBY 代码复制
  1. EX.some_method 1,2

定位到 arg[2] += 1
作者: 晴兰    时间: 2014-2-22 21:35
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-22 22:05
本帖最后由 余烬之中 于 2014-2-23 13:01 编辑

话说太短的话可以加功能嘛……
增强实用性 比如
RUBY 代码复制
  1. if $RGSS_SCRIPTS[0][3].include?("8e860c510b6653364928f6adf99b3283")
  2.  
  3.   $RGSS_SCRIPTS.each do |s|
  4.     s[3].gsub!("rescue!"){"rescue exstore "}
  5.   end
  6.  
  7.   module Reraise
  8.     $exstack = [] # 栈
  9.     # 重抛出异常
  10.     def reraise(ex)
  11.       raise ex.class, ex.message, ex.backtrace
  12.     end
  13.     # 压栈
  14.     def exstore
  15.       $exstack.push($!)
  16.     end
  17.     # 退栈
  18.     def exlast
  19.       return true if $exstack.empty?
  20.       reraise $exstack.pop
  21.     end
  22.   end
  23.  
  24.   include Reraise
  25.  
  26. else
  27.   warning = defined?(Audio.setup_midi) ? method(:msgbox) : method(:print)
  28.   warning.call "请将此脚本置于最顶端 → →"
  29. end
然后测试用例
RUBY 代码复制
  1. class TEST
  2.   def a
  3.     puts "a pre"
  4.     raise NoMethodError, "A" rescue!
  5.     puts "a done"
  6.   end
  7.  
  8.   def b
  9.     puts "b pre"
  10.     raise NoMethodError, "B" rescue!
  11.     puts "b done"
  12.   end
  13. end
  14.  
  15. t = TEST.new
  16.  
  17.  
  18.  
  19. #~ # 用例一
  20. #~ puts "picnic~"
  21. #~ t.a
  22. #~ puts "have a break~"
  23. #~ exlast rescue puts "a small problem...#{$!}"
  24. #~ puts "let's go home!"
  25.  
  26. #~ puts "======================================"
  27.  
  28. #~ puts "picnic~ (2nd)"
  29. #~ t.a
  30. #~ puts "have a break~"
  31. #~ exlast #rescue puts "a small problem...#{$!}"
  32. #~ puts "let's go home! (you've got no chance!)"
  33.  
  34. # 用例二
  35. puts "picnic~"
  36. t.a
  37. t.b
  38. loop do
  39.   (r = exlast) rescue puts "a small problem...#{$!}"
  40.   break if r
  41. end

作者: 晴兰    时间: 2014-2-22 22:17
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-23 09:07
虽然明白是在干什么,但是总觉得没什么用……
作者: 余烬之中    时间: 2014-2-23 13:01
这个好像达不到应有的效果……
  1. raise Exception, "" rescue;
复制代码
大概是因为Exception类的缘故  一般的异常都能捕捉 但Exception、SystemExit这样的都不会捕捉到……
于是把【rescue_save】改成了【rescue!】(这个有“于是”的关系吗 0.0

=============================
@taroxd 这个用处很大啊…………
你难道没有过事件报错,打开脚本编辑器于是跳转到【eval(script)】的经历吗……然后为了找到错误处,一个一个的设置断点→ →
尤其是那种强调功能的脚本,比强调界面的脚本更难找…………
作者: 晴兰    时间: 2014-2-23 13:03
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-23 13:21
晴兰 发表于 2014-2-23 13:03
其实rescue只能捕捉StandardError,所以这个例子确实有问题。。。有一个异常强度弱化:

def weaken

或许可以这样?
RUBY 代码复制
  1. $RGSS_SCRIPTS.each do |s|
  2.    s[3].gsub!(/^(.*?)rescue(?::|;|d\.)/){"weaken{#{$1}} rescue expush "}
  3. end


==========

eval有多个参数吗  我一直不知道
能不能详细的解释一下?
作者: 晴兰    时间: 2014-2-23 13:49
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1