2012-01-06 3 views
9

필자가 작성한 일부 코드와 충돌하는 최상위 클래스를 정의하는 보석을 감안할 때, 모든 클래스가 모듈 내에 그룹화되는 방식으로 보석을 요구할 수 있습니까? 내가 정의 할 수 있니? 예를 들어, unsafe_gem는 클래스를 정의하는 경우 :Ruby gem을 사용자 정의 네임 스페이스에로드하십시오.

class Word 
    # ... some code 
end 

내가 좋아하는 뭔가를해야합니다 :

Word.new # => The class I defined. 
SafeContainer::Word.new # => The class defined by the gem. 

일부 자세한 내용 : 그래서 구별 할 수

class Word 
    # My word class. 
end 

module SafeContainer 
    # This obviously doesn't work 
    # (i.e. the gem still defines ::Word). 
    require 'unsafe_gem' 
end 

을 사이 내 코드 (예 : 'Word'클래스)는 이미 자체 네임 스페이스에 래핑되어 있습니다. 그러나 최상위 네임 스페이스 아래에서 일부 클래스를 직접 액세스 할 수 있도록 "구문 설탕"형식을 사용하도록 사용자에게 옵션을 제공 할 수 있기를 바랍니다. 그러나 이것은 최상위 클래스를 정의하는 사용하고있는 보석 중 하나와 이름 충돌을 일으 킵니다. 보석이 실제로 거기에있는 세계적으로 정의 된 클래스에 실제로 의존하기 때문에 현재 제안 된 솔루션 중 어느 것도 작동하지 않습니다. 클래스를 정의 해제하면 보석이 깨집니다. 물론,이 보석은 하나 이상의 파일을 가지고 있으며 모듈에 파일을 개별적으로 요구하는 것은 매우 취약한 해결책으로 보인다. 현재 내가 찾은 유일한 해결책은 다음과 같습니다.

begin 
    # Require the faulty gem. 
    require 'rbtagger' 
rescue 
    # If syntactic sugar is enabled... 
    if NAT.edulcorated? 
    # Temporarily remove the sugar for the clashing class. 
    Object.const_unset(:Word); retry 
    else; raise; end 
ensure 
    # Restore syntactic sugar for the clashing class. 
    if NAT.edulcorated? 
    Object.const_set(:Word, NAT::Entities::Word) 
    end 
end 

왜 그런지 모르지만 내 발톱이 말려 있습니다. 누구보다 나은 해결책이 있습니까?

답변

4

또 다른 가능한 대답은 this입니다. 당신 require 당신이 당신의 자신의 클래스를 정의하기 전에 당신이 unsafe_gem는 하나 개의 클래스를 정의하는지 확인해야하고,

require 'unsafe_gem' 
namespaced_word = Word 
Word = nil 


# now we can use namespaced_word to refer to the Word class from 'unsafe_gem' 

#now your own code 
class Word 
    #awesome code 
end 

: 클래스와 모듈은 사실의

테이크의 장점은 너무처럼 객체 및 모듈을 사용하므로 실수로 자신의 콘텐츠를 nil으로 설정하지 않아도됩니다.

1

나는 최선의 방법은 모듈에 자신의 코드를 래핑하는 것이라고 생각한다. 얼마나 많은 코드를 작성 했느냐에 따라, 이것은 큰 고통이 아닐 수도 있습니다. 그러나 코드가 다른 사람과 충돌하지 않도록하는 가장 좋은 방법입니다.

그래서 당신의 Word 클래스는

module LoismsProject 
    class Word 
    #some awesome code 
    end 
end 

안전하게 require 'unsafe_gem' 할 수있는 방법이된다.

0

간단한 대답은 "아니오"입니다.

'word.rb'파일이있는 경우;

class Word 
    def say 
    puts "I'm a word" 
    end 
end 

우리가 시도하고 require는 항상 전역에로드됩니다.

보석이 하나의 파일 인 것을 알고 있다면 다음을 수행 할 수 있습니다.

module SafeContainer 
    module_eval(File.read("word.rb")) 
end 

그러나 이것은 귀하의 경우에는 효과가 없을 것입니다.

관련 문제