2016-09-12 6 views
0

타사 오픈 소스 라이브러리를 사용하고 있습니다. 도서관에서 타사 라이브러리 방법에 액세스

는, 하나 개의 파일이 ( 아아-BBB/Ccc.rb)의 코드는 다음과 같습니다 : 내 루비 프로젝트에서
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

'모듈 Aaa 모듈 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 

이러한 동등한 처리 한 두 가지 방법을 정의한 정규화 된 이름은 Aaa::Bbb::Ccc::get_dataMyMod::my_func입니다. my_func이 실행되면 MyMod 모듈에서 먼저 get_data 메서드를 검색하지만 하나도 존재하지 않습니다. 그래서 최상위 객체 (모듈)를 검색하여 get_data 메쏘드를 찾는다. 그곳에 있지 않다면 NoMethodError 예외로 실패한다.

직접 위의 방법을 사용하지 않는 다른 모듈을 살펴볼 수있는 두 가지 방법이 있습니다.

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

둘째, 당신은 자신의 모듈의 이름 공간에 다른 모듈에서 모든 방법을 가지고 include를 사용할 수 있습니다 : 첫째, 당신은 단순히 완전한 이름으로 직접 호출 할 수 있습니다

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

당신 위의 예제에서 이라는 초기 값을 사용하여 Aaa에 대한 검색을 최상위 수준 개체/모듈에서 시작하도록합니다.이 간단한 예제에서 필요하지 않습니다,하지만 당신은 포함을 발견하는 것과 Aaa 대신 ::Aaa의 사용

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

으로 중첩 등으로 마치 때문에 중첩 모듈을 상대하고 일반적으로 좋은 연습입니다 ::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

흠 ... 아직도 제 3 자 라이브러리 인 https://github.com/calabash/calabash-android/blob/master/ruby-gem/lib/calabash-android/operations.rb와 같은 오류가 발생합니다. 'get_preferences (name) '를 호출해야합니다. –

0

require 인터프리터의 현재 인스턴스에 지정된 파일을 처리하지만, 현재의 이름 공간에 영향을주지 않습니다 :

관련 문제