红宝石异常的遗产继承与动态产生的课程
-
09-06-2019 - |
题
我是新来的宝石,所以我有些麻烦了解这个奇怪的异常问题,我有。我使用的是红宝石的aaws宝石访问亚马逊ECS: http://www.caliban.org/ruby/ruby-aws/.这样限定了一类Amazon::您错误:
module Amazon
module AWS
# All dynamically generated exceptions occur within this namespace.
#
module Error
# An exception generator class.
#
class AWSError
attr_reader :exception
def initialize(xml)
err_class = xml.elements['Code'].text.sub( /^AWS.*\./, '' )
err_msg = xml.elements['Message'].text
unless Amazon::AWS::Error.const_defined?( err_class )
Amazon::AWS::Error.const_set( err_class,
Class.new( StandardError ) )
end
ex_class = Amazon::AWS::Error.const_get( err_class )
@exception = ex_class.new( err_msg )
end
end
end
end
end
这意味着,如果你得到一个errorcode喜欢 AWS.InvalidParameterValue
, 这将产生(在其异常变量)一个新的类 Amazon::AWS::Error::InvalidParameterValue
这是一个子类的 StandardError
.
现在这里是哪里变得怪异。我有一些代码,是这样的:
begin
do_aws_stuff
rescue Amazon::AWS::Error => error
puts "Got an AWS error"
end
现在,如果 do_aws_stuff
抛出了一个 NameError
, 我救块被触发。看来,亚马逊::您:误差不超类的产生错误的-我猜因为它是一个模块的一切是一个子类的吗?当然,如果我这样做:
irb(main):007:0> NameError.new.kind_of?(Amazon::AWS::Error)
=> true
它说的 true
, 我发现混乱,特别是鉴于这样的:
irb(main):009:0> NameError.new.kind_of?(Amazon::AWS)
=> false
什么,以及如何我是应该单独出AWS错误的其他类型的错误?我应该做些什么,如:
begin
do_aws_stuff
rescue => error
if error.class.to_s =~ /^Amazon::AWS::Error/
puts "Got an AWS error"
else
raise error
end
end
这似乎是非常痛错误引发不流AWSError么-他们在提出这样的:
error = Amazon::AWS::Error::AWSError.new( xml )
raise error.exception
因此例外我要找到 rescue
从所产生的异常类型,只有继承StandardError.
为了澄清,我有两个问题:
为什么是NameError,红宝石建成的异常,
kind_of?(Amazon::AWS::Error)
, ,这是一个模块?
回答: 我不得不说include Amazon::AWS::Error
在我的文件,认为它是一种喜欢一个Java进口或C++包括。这实际上做的是添加一切定义Amazon::AWS::Error
(现在和将来),以隐含的核心类,这是一个祖先的每一类。这意味着 任何东西 将通过kind_of?(Amazon::AWS::Error)
.我可以如何最佳区分的动态创建的例外情况
Amazon::AWS::Error
从随机的其他例外情况,从其他地方?
解决方案
好吧,我会尽力帮助在这里:
第一个模块是不是一类的,它可以让你混合行为中的一类。第二个看以下例子:
module A
module B
module Error
def foobar
puts "foo"
end
end
end
end
class StandardError
include A::B::Error
end
StandardError.new.kind_of?(A::B::Error)
StandardError.new.kind_of?(A::B)
StandardError.included_modules #=> [A::B::Error,Kernel]
kind_of?告诉你,是的,错误不会拥有所有的:B::错误的行为(这是正常的,因为它包括:B::错误)然而其中不包括所有行为,从A::B和因此不是一个:B。(鸭打字)
现在有一个很好的机会,红宝石有关信息请参阅重新开放一个超类的NameError和包括Amazon::您错在那里。(猴子的修补)
你可以找出通过程序里的模块包含的层次结构如下:
class Class
def has_module?(module_ref)
if self.included_modules.include?(module_ref) and not self.superclass.included_modules.include?(module_ref)
puts self.name+" has module "+ module_ref.name
else
self.superclass.nil? ? false : self.superclass.has_module?(module_ref)
end
end
end
StandardError.has_module?(A::B::Error)
NameError.has_module?(A::B::Error)
关于你的的第二个问题,我看不到任何东西比
begin
#do AWS error prone stuff
rescue Exception => e
if Amazon::AWS::Error.constants.include?(e.class.name)
#awsError
else
whatever
end
end
(编辑上的代码不工作是:名字包括模块的前缀它不是这种情况的常量阵列。你肯定应该接触lib维护者的AWSError类看起来更像是一个厂类对我说:/)
我没有红宝石的有关信息请参阅在这里和卡利班网站被封锁的公司的防火墙,所以我不能测试更进一步。
关于包括:可能的事情做猴子补上StandardError层次结构。我不知道了,但最有可能这样做的根本文件之外的每一个方面是包括模块上的象或对象上元类.(这是什么会发生在移民和难民委员会,在那里默认的上下文是目的,不肯定的关于在文件)
从 镐上模块 :
A couple of points about the include statement before we go on. First, it has nothing to do with files. C programmers use a preprocessor directive called #include to insert the contents of one file into another during compilation. The Ruby include statement simply makes a reference to a named module. If that module is in a separate file, you must use require to drag that file in before using include.
(编辑-我不能似乎是能够使用浏览器:/耶锁定在平台)
其他提示
好吧,从我可以告诉:
Class.new( StandardError )
是创建一个新的类StandardError为基类,所以它不是一个Amazon::您:错误的。这只是定义中的模块,这可能是为什么它是一个kind_of?Amazon::您:错误。它可能不是一个kind_of?Amazon:资,因为可能的模块不巢的目的kind_of??
对不起,我不知道模块很好的红宝石,但最肯定的基类将是StandardError.
更新:通过这种方式, 从红宝石文件:
obj。kind_of?(class)=>真正的或虚假的
Returns true if类的obj,或者如果类是一个超类的obj或模块包括在obj。
只是想报:我同意这是一个错误的lib代码。它也许应该读作:
unless Amazon::AWS::Error.const_defined?( err_class )
kls = Class.new( StandardError )
Amazon::AWS::Error.const_set(err_class, kls)
kls.include Amazon::AWS::Error
end
一个问题你遇到的是, Amazon::AWS::Error::AWSError
实际上不是一个例外。时 raise
是所谓的,这看起来看,如果第一个参数作出响应的 exception
方法和将使用的结果,而不是。任何一个亚类的 Exception
将返回自己的时候 exception
是所谓的,你可以做的事情一样 raise Exception.new("Something is wrong")
.
在这种情况下, AWSError
已 exception
设置作为一个属性读者其它值定义,在初始化之类的东西 Amazon::AWS::Error::SOME_ERROR
.这意味着,当你打电话 raise Amazon::AWS::Error::AWSError.new(SOME_XML)
Ruby结束了 Amazon::AWS::Error::AWSError.new(SOME_XML).exception
这将返回的一个实例 Amazon::AWS::Error::SOME_ERROR
.正如所指出的另一反应者,此类是直接的子 StandardError
而不是被一个子类的共同亚马逊的错误。直到这是纠正,让的解决方案可能是你最好的选择。
我希望,帮助解释更多的是怎么在幕后。