用于向库代码添加模块的Ruby首选方法?

时间:2011-10-19 23:18:30

标签: ruby module

向库ruby代码添加模块功能的首选方法是什么?

请考虑以下事项:

module MyExceptions
    class SomethingBadHappenedTheLibarayDesignerDidntConsider < StandardError; end
end

如何将MyExceptions模块添加到我无法控制的类中?


更新,在my_library_class_exceptions.rb我做了:

class LibraryClass
    include MyExceptions
end
module MyExceptions
    class SomethingBadHappenedTheLibarayDesignerDidntConsider < StandardError; end
end

但控制台返回:NameError: uninitialized constant LibraryClass::MyExceptions

3 个答案:

答案 0 :(得分:2)

在Ruby中,您可以稍后打开任何类的定义并进行更改。

以下是重写分部以通过重新打开以前创建的类来使用自定义异常的设计示例。

class Foo
  def divide(a, b)
    a/b
  end
end

foo = Foo.new()
foo.divide(1, 0)

module MyExceptions
  class MyDivisionError < StandardError; end
end

class Foo
  include MyExceptions
  alias old_divide divide
  def divide(a, b)
    old_divide(a, b)
  rescue ZeroDivisionError
    raise MyDivisionError
  end
end

foo.divide(1, 0)

答案 1 :(得分:1)

查看您的更新,它不起作用的简单原因是顺序:您在定义之前使用MyExceptions。 文件的固定版本 - 重新打开库类:

require 'thelib'

module MyExceptions
    class SomethingBadHappenedTheLibarayDesignerDidntConsider < StandardError; end
end
LibraryClass.class_eval do
    include MyExceptions
end

这个类eval技巧可以说是重新开放课程比单纯class LibraryClass更安全的方法:如果你错过了这个类名,它会警告你。

顺便说一句:我真的没有看到你计划如何使用MyException ...这可能意味着更多的猴子修补和/或包装部分库。

更新:以上假设您在同一目录中thelib.rb至少包含以下内容:

class LibraryClass
end

答案 2 :(得分:0)

我通过修改一些事情并改变一些事情来实现这一目标。

  1. 事实证明LibraryClass实际上并不是一个类,而是一个模块。所以我改变了:

    类LibraryClass     包括MyExceptions 端

  2. 进入:

    module LibraryClass
        module MyExceptions
            class SomethingBadHappenedTheLibarayDesignerDidntConsider < StandardError; end
        end
    end
    
    1. 然后我将library_class.rb移至lib\library_class_extensions.rb并确保lib是自动加载路径的一部分。
    2. 然后在初始化程序中,我调用了require 'library_class_extensions'
    3. 我认为这是我试图完成的行为的更好模式,因为这实际上更多是app/model类型代码的库类型代码。

      我对所有人给出的答案进行投票,表达他们的英勇努力。