2016-09-12 14 views
0

私はサードパーティのオープンソースライブラリを使用しています。ライブラリで第三者のライブラリメソッドにアクセス

は、一つのファイル(AAA-BBB/Ccc.rb)さんがあり、コードは次のようになります。私のRubyプロジェクトで

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

、私はから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) 

なぜ?この問題を解決するには?

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 
+0

私は 'module Aaa module Bbb'という行に問題があると思いますが、実際の行はどのように見えますか? –

+0

名前を除いて全く同じ行です。 –

+0

OKは3段階のネスティングのようですが、私は自分の答えを更新しました。 –

答えて

0

は、あなた自身のモジュールに必要なモジュールをincludeする必要があります。別の名前空間から現在の名前空間にメソッドをインポートするには、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 

これと同等のものを処理した2つのメソッドを定義しています完全修飾名はAaa::Bbb::Ccc::get_dataおよびMyMod::my_funcです。 my_funcが実行されると、モジュールMyModの最初にget_dataメソッドを検索しますが、1つではありません。したがって、最上位レベルのオブジェクト(モジュール)をget_dataメソッドで検索し、見つからない場合は、NoMethodError例外で失敗します。

メソッドの直上にない他のモジュールを見る方法は2通りあります。

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を使用すると、囲んを見つけるだろうので、それは一般的に良い練習です::Aaaモジュールの代わりに::Xxx::Aaaモジュールを使用してください。

も注意してください、それは深いネストを行うときに、便利なことができネスティングとmodule/endの使用を節約するために

module Aaa::Bbb::Ccc; module Ddd 
    def self.f; ...; end 
end; end 

を使用して、モジュールを定義することができますが、場合によっては確認する必要がありますことを上記のように、モジュールAaaAaa::Bbbは既にロードされている前のコードで定義されています。

+0

そして、私はまだ '' Aaa-Bbb/Ccc ''が必要です。 –

+0

@ Leem.finはい、ファイルが必要であり、モジュールを含める必要があります。 –

+0

ええと...私はまだ同じエラーが発生しています。サードパーティ製のライブラリです:https://github.com/calabash/calabash-android/blob/master/ruby-gem/lib/calabash-android/operations.rb 'get_preferences(name)'を呼び出す必要があります –

0

requireはインタプリタの現在のインスタンス内の指定されたファイルを処理しますが、あなたの現在の名前空間には影響を与えません。

関連する問題