如何确定LocalJumpError的由来?

如何确定轻松编程是否LocalJumpError出现了从来电者的眼前未能提供一个所需块的方法,或从该法和其他方法调用它在更深?

通过“轻松,”我的意思是我想避免串检查/使用regexen在$!.backtrace 。 适用于1.8和1.9的溶液也是优选的。

动机:当我把事情弄糟一个方法调用在Ruby中,这通常是因为我拼写错误的方法NoMethodError得到了错误的参数(数量ArgumentError或忽视传递一个必要的块LocalJumpError

对于红宝石代理或装饰包装对象,我想从实现者或环境错误 ,可以引发错误的同一类别区分这些来电者或API错误。 例如:

... def method_missing(sym, *args, &block) @wrapped.__send__(sym, *args, &block) rescue NoMethodError raise MyApp::BadInvocation, "duh - no such method" unless @wrapped.respond_to?(sym) raise rescue ArgumentError raise MyApp::BadInvocation, "duh - wrong arg count" \ unless _args_fit_arity?(@wrapped.method(sym), args) raise rescue LocalJumpError # XXX - what is the test? raise end

--------------解决方案-------------

要了解是否LocalJumpError被遗忘传递一个块的用户造成的,你需要知道两件事情:无论用户提供的块和方法是否需要一个块。 第一个很简单:只需检查BLK是否为零。 然而,第二个是不可能的(纯红宝石至少)。

所以我想解析堆栈跟踪是你最好的选择。

一个可以检查的相对深度backtrace到从随后的误差在调用栈中更深做出最大努力判别呼叫者错误:

def lje_depth_from_send
Class.new { def lje; yield end }.new.__send__ :lje
rescue LocalJumpError
return $!.backtrace.size - caller(0).size
end

def method_missing(sym, *args, &block)
...
rescue LocalJumpError
if !block_given? and ($!.backtrace.size - caller(0).size) == lje_depth_from_send
raise MyApp::BadInvocation, "duh - you forgot to supply a block"
end
raise
end

有趣的是,MRI 1.8这个相对深度计算改变MRI 1.9 -前轨道发送 ,后者似乎静静地忽略它(ALA Perl的goto &sub ,也许?)为例。 (在1.9以下时,LJE回溯比 caller(0)堆栈,因为1.9明确计数rescue块作为一个离散堆栈帧)。

现在,这可能不是在非工作的MRI,但我怀疑调用堆栈的解析将便携式从一个实现到另一个,或者。

分类:红宝石 时间:2015-03-15 人气:4
本文关键词: 红宝石,代理,装饰
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.336 (s). 10 q(s)