2010-05-24 3 views
4

내부에 많은 클래스가있는 모듈을 가진 Ruby 라이브러리를 작성 중입니다. 초기화 자이 호출/볼 수 있도록 이러한 클래스의 대부분은 스크립트를 호출하여 유용하고 수정해야하지만, 나는 (의 일부)를하지 않으 :Ruby 라이브러리 작성하기 - 모듈 외부에서 메소드 숨기기

module MyLib 
    class Control 
    def initialize 
     # They can use this 
    end 

    def do_stuff 
     Helper.new('things') 
    end 
    end 

    class Helper 
    # Shouldn't be visible 
    def initialize(what) 
     @what = what 
    end 

    def shout 
     @what 
    end 
    end 
end 

c = MyLib::Control.new 
h = c.do_stuff 
p h.shout 
# => "things" 
#^All of this is desired 

# v This is undesirable 
p MyLib::Helper.new('!') 
# => <MyLib::Helper @what='!'> 

그 다음 나는 또한 좋겠, 간단한 일이 있다면 생성 된 RDoc도 Helper 클래스의 .new 메소드를 포함하지 않아도됩니다. 어떤 아이디어?

읽어 주셔서 감사합니다.

답변

3

@Matthew가 지적한 것처럼 내 원래의 대답은 완전히 잘못되었습니다. 그러나 다른 해결 방법이 있습니다. 예를 들어, Control에 클래스 변수에 익명의 클래스를 지정할 수, 여전히 class_eval를 사용하여 정상적으로 방법을 정의

module MyLib 
    class Control 
    def initialize 
    end 

    def do_stuff 
     @@helper.new('things') 
    end 

    @@helper = Class.new 
    @@helper.class_eval do 
     def initialize(what) 
     @what = what 
     end 

     def shout 
     @what 
     end 
    end 
    end 
end 

c = MyLib::Control.new 
h = c.do_stuff 
p h.shout 

여전히 "things"를 기록 스 니펫을,하지만 지금은 더있다 @@helper에 액세스하려면 클래스 변수를 통하는 것이 좋습니다. 누군가 이 실제로 인 경우 내 Control 클래스를 다시 열거 나 class_eval을 사용하고 싶다면 아무것도 막을 수는 없지만 그것은 역동적 인 언어로 처리해야합니다.

익명 클래스를 클래스 변수에 할당하여 한 번만 생성되도록했습니다. 하지만 익명의 클래스를 여러 번 재정의하는 것에 신경 쓰지 않는다면 인스턴스 변수가 될 수있는 이유가 없습니다.

+0

불행히도 이것은 고장났습니다. Helper가 현재 제어 상태이므로 구문 오류가 발생합니다. 그러나'p MyLib :: Control :: Helper.new ('!')'는 개인용에도 불구하고 작동합니다. –

+0

@Matthew : 네 말이 맞아. 그건 내 멍청한 실수 였어. 나는 그런 벙어리 오류의 희생자가 아닌 다른 해결 방법을 작성했지만 여전히 문제를 해결합니다. –

2

루비는 access control입니다.

+0

'Control' 클래스에서'Helper.new'를 호출하지 못하도록 비공개로 정의하지 않으시겠습니까? –

관련 문제