访问第三方库方法

时间:2016-09-12 13:00:12

标签: ruby

我正在使用第三方开源库。

在库中,有一个文件( Aaa-Bbb / Ccc.rb )的代码如下所示:

module Aaa
  module Bbb
    module Ccc
      def get_data
        ...
      end
    end
  end
end

在我的Ruby项目中,我需要从上面的模块调用get_data方法。所以我尝试了这个:

require 'Aaa-Bbb/Ccc'
module MyMod
  def my_func
     # Error: undefined method 'get_data' for MyMod:Module (NoMethodError)
     data = get_data
  end
end

当我运行上面的代码时,我收到错误:

undefined method 'get_data' for MyMod:Module (NoMethodError)

为什么呢?如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您需要在自己的模块中include所需的模块:

require 'Aaa-Bbb/Ccc'

module MyMod
  # Including the required module to make all its methods available here.
  include Aaa::Bbb::Ccc

  def my_func
     data = get_data
  end
end

答案 1 :(得分:0)

require将处理解释器的当前实例中的给定文件,但不会影响当前的命名空间。您使用include将方法从另一个名称空间导入当前名称空间;请注意include未读入文件或与文件有任何其他关系。

所以,如果你从

开始
require 'Aaa-Bbb/Ccc'

module MyMod
    def self.my_func; data = get_data; end
end

(请注意,我在函数名称前添加了self.,因为我假设您的示例的性质是您不想在此处使用对象。)

在处理require方法后,解释器处理了等效的

module Aaa; module Bbb; module Ccc
    def self.get_data; ...; end
end; end; end

module MyMod
    def self.my_func; data = get_data; end
end

这定义了两种方法,其完全限定名称为Aaa::Bbb::Ccc::get_dataMyMod::my_func。执行my_func后,它会首先搜索模块get_data中的MyMod方法,但没有一个方法。因此,它会在顶级对象(模块)中搜索get_data方法,而不是在那里找到它,会因您的NoMethodError异常而失败。

有两种方法可以查看其他模块,而不是直接在您的方法之上。首先,您只需使用完全限定名称直接调用它:

data = ::Aaa::Bbb::Ccc::get_data

其次,您可以使用include将来自其他模块的所有方法带入您自己模块的命名空间中:

include ::Aaa::Bbb::Ccc
data = get_data

您会注意到我在上面的示例中使用了一个初始::来强制搜索Aaa从顶级对象/模块开始。在这个简单的例子中,这不是必需的,但是当你处理深度嵌套的模块时,这通常是很好的做法,因为如果你在嵌套中,例如

module Xxx; module Aaa; module MyMod
    def self.my_func; ...; end
end; end; end

仅使用Aaa代替::Aaa会找到封闭的::Xxx::Aaa模块,而不是顶级::Aaa模块。

另请注意,在进行深度嵌套时,使用

定义模块会很方便
module Aaa::Bbb::Ccc; module Ddd
    def self.f; ...; end
end; end

保存嵌套和module / end的使用,但您确实需要确保在上述情况下模块AaaAaa::Bbb已在先前已加载的代码中定义。