使用动态生成的类进行Ruby异常继承

使用动态生成的类进行Ruby异常继承,第1张

概述我是 Ruby的新手,所以我在理解我遇到的这个奇怪的异常问题时遇到了一些麻烦.我正在使用ruby-aaws gem访问Amazon ECS: http://www.caliban.org/ruby/ruby-aws/.这定义了一个类Amazon :: AWS:错误: module Amazon module AWS # All dynamically generated excepti 我是 Ruby的新手,所以我在理解我遇到的这个奇怪的异常问题时遇到了一些麻烦.我正在使用ruby-aaws gem访问Amazon ECS: http://www.caliban.org/ruby/ruby-aws/.这定义了一个类Amazon :: AWS:错误:

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  endend

这意味着如果您获得类似AWS.InvalIDParameterValue的错误代码,则会生成(在其异​​常变量中)新类Amazon :: AWS :: Error :: InvalIDParameterValue,它是StandardError的子类.

现在这里变得奇怪了.我有一些看起来像这样的代码:

begin  do_aws_stuffrescue Amazon::AWS::Error => error  puts "Got an AWS error"end

现在,如果do_aws_stuff抛出nameError,我的救援块就会被触发.似乎Amazon :: AWS :: Error不是生成错误的超类 – 我猜是因为它是一个模块,所有东西都是它的子类?当然如果我这样做:

irb(main):007:0> nameError.new.kind_of?(Amazon::AWS::Error)=> true

它说的是真的,我觉得很困惑,特别是考虑到这一点:

irb(main):009:0> nameError.new.kind_of?(Amazon::AWS)=> false

发生了什么,以及我如何将AWS错误与其他类型的错误分开?我应该这样做:

begin  do_aws_stuffrescue => error  if error.class.to_s =~ /^Amazon::AWS::Error/    puts "Got an AWS error"  else    raise error  endend

这看起来格格不入.抛出的错误也不是类AWSError – 它们是这样引发的:

error = Amazon::AWS::Error::AWSError.new( xml )raise error.exception

所以我想要解决的例外是生成的异常类型,它们只继承自StandardError.

澄清一下,我有两个问题:

>为什么nameError是一个内置异常的Ruby,一个kind_of?(Amazon :: AWS :: Error),它是一个模块?
答:我曾说过在我的文件顶部包含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  endendclass StandardError  include A::B::ErrorendStandardError.new.kind_of?(A::B::Error)StandardError.new.kind_of?(A::B)StandardError.included_modules #=> [A::B::Error,Kernel]

的种类?告诉你是的,错误确实拥有All A :: B :: Error行为(这是正常的,因为它包含A :: B :: Error)但是它不包括A :: B的所有行为,因此不是A :: B种类. (鸭子打字)

现在很有可能ruby-aws重新打开nameError的超类之一并包含Amazon :: AWS:Error. (猴子补丁)

您可以通过编程方式找到模块包含在层次结构中的位置,其中包含以下内容:

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          endendStandardError.has_module?(A::B::Error)nameError.has_module?(A::B::Error)

关于你的第二个问题,我看不出更好的东西

begin #do AWS error prone stuffrescue Exception => e  if Amazon::AWS::Error.constants.include?(e.class.name)    #awsError  else    whatever  end end

(编辑 – 上面的代码不能正常工作:name包含模块前缀,这不是常量数组的情况.你应该联系lib维护者,AWSError类看起来更像是工厂类:/)

我这里没有ruby-aws,并且校准站点被公司的防火墙阻止,所以我无法进一步测试.

关于include:可能是在StandardError层次结构上进行猴子修补的事情.我不确定,但最有可能在每个上下文之外的文件的根目录下执行它包括Object上的模块或Object元类. (这是在IRB中会发生的情况,其中默认上下文是Object,在文件中不确定)

从pickaxe on modules:

在我们继续之前关于包含声明的几点.首先,它与文件无关. C程序员使用一个名为#include的预处理程序指令在编译期间将一个文件的内容插入到另一个文件中. Ruby include语句只是引用一个命名模块.如果该模块位于单独的文件中,则必须使用require在使用include之前拖动该文件.

(编辑 – 我似乎无法使用此浏览器发表评论:/ yay for locked in platforms)

总结

以上是内存溢出为你收集整理的使用动态生成的类进行Ruby异常继承全部内容,希望文章能够帮你解决使用动态生成的类进行Ruby异常继承所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1212459.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存