2012-09-19 6 views
0

내 모듈 이름 만 사용하여 서브 클래스에 액세스하고 싶습니다.이름을 지정하지 않고 모듈 서브 클래스 호출

module MyModule 
    class UselessName 
     include OtherModel 
     # only self method 
     def self.x 
     end 
    end 
    # No other class 
end 

내가 MyModule.x하지 MyModule::UselessName.x

내가 수업 시간에 내 모듈을 변환 할 수 쓰고 싶지만, 내가 RoR에 도우미를 사용하고 난 그 인 MyModule 선호는 모듈이 아닌 클래스 남아있다.

이 방법이 있습니까? 감사)

+0

달성하려는 목표는 무엇입니까? 왜'UselessName' 클래스를 생략하지 않습니까? – Vapire

+0

내 질문을 편집했습니다. 나는 동일한 메소드 이름을 가진 다른 모듈을 가지고있다. –

+0

그래서? 당신은'MyModule :: x'와 같은 메소드를 각각 호출하기를 원한다고 말합니다. 그래서 MyModule.x'는 클래스를 생략하고, 모듈에 넣고 이것을 호출합니다 ... 아니면 뭔가 빠졌습니까? 추신 : 메서드 이름은 소문자 여야합니다. 대문자는 상수입니다. CONSTANT – Vapire

답변

1

확인이 그것이 있어야하는 방식이 아니기 때문에 당신은 앱 디자인을 overthink해야하지만, 여기 요 - 이러한 방법 및 결정의 점점 목록을 모듈의 프록시.

얻기 목록은 조금 까다로울 수 있습니다 여기에

MyModule::UselessName.public_methods(false) - MyModule::UselessName.superclass.public_methods(false) 

우리가 모든 공용 클래스 메소드의 목록을 시작하고 모든 슈퍼 클래스의 공용 클래스 메소드의 목록을 뺍니다.

이제 메서드 이름을 알고 있다고 가정하면 프록시 메서드를 만들어야합니다.

metaclass = class << MyModule; self; end 
metaclass.send(:define_method, :x) do |*args, &block| 
    MyModule::UselessName.send(:x, *args, &block) 
end 

이 코드는 런타임에 다음 정의와 동일하게 만듭니다.

module MyModule 
    def x(*args, &block) 
    MyModule::UselessName.send(:x, *args, &block) 
    end 
end 

그럼 간단한 기능으로 정리해 보겠습니다.

def make_proxies(mod, cls) 
    methods = cls.public_methods(false) - cls.superclass.public_methods(false) 
    metaclass = class << mod; self; end 

    methods.each do |method| 
    metaclass.send(:define_method, method) do |*args, &block| 
     cls.send(method, *args, &block) 
    end 
    end 
end 

이제 모듈과 클래스를 호출하면됩니다. "대상"모듈은 클래스를 소유 한 "소스"모듈과 다를 수 있으므로 모든 메소드 (이름이 다르거 나 클래스 이름을 사용하여 접두어로 붙이는 경우)를 하나의 모듈에 적용 할 수 있습니다. 예 : 당신의 경우에는 다음 전화를하십시오.

make_proxies(MyModule, MyModule::UselessName) 
+0

답변 해 주셔서 감사합니다. 그것은 효과적으로 할 수있는 좋은 방법이지만, 좀 더 짧은 것을 찾고 있었는데, 키워드 또는 특별한 속성을;) –

+0

글쎄,이 함수를 lib 디렉토리에 넣고 "키워드"로 사용하십시오. – iced

+0

내가 할 수는 있지만,이 세부 사항에 대해서만 내 앱을 복잡하게 만들고 싶지는 않습니다. –

1
좋아, 난 당신이 무슨 뜻 무슨 생각을 달성하는 아주 더러운 방법을 발견했습니다

:

module MyModule 
    class UselessName 
    include OtherModule 

    # have whatever you want here 
    end 

    def self.x 
    # whatever 
    end 
end 

을 그래서 어딘가 코드에서 당신이 할 수있는, 그리고 나는 이것이 매우 IS 반복 더러운!

MyModule.methods(false).each do |m| 
    # m = method 

    # now you can redefine it in your class 
    # as an instance method. Not sure if this 
    # is what you want though 
    MyModule::UselessName.send(:define_method, :m) do 
    # in this NEW (it's not the same) method you can 
    # call the method from the module to get the same 
    # behaviour 
    MyModule.send(m) 
    end 
end 

는 전 클래스에의하거나 예외를 throw하는 경우, 당신이 시도해야하는 경우이 같은 이름의 인스턴스 메서드를 덮어 쓰는 경우 나도 몰라. 제 생각에는

두 가지로하자 ... 분할 문제를

+0

좋아요, MyModule :: UselessName.x 대신 MyModule.x를 쓰고 싶다면 쓰는 것이 적어지기 위해서입니다.그렇다면 당신의 솔루션은 내가 찾고있는 것이 아니라고 생각합니다.하지만 고맙습니다. ^^ 저는 MyModule을 수업 시간에 변형시킬 것입니다. –

관련 문제