2012-11-11 20 views
7

Mam klasy i moduł, które mają te same nazwy:Patrz metody w module o takiej samej nazwie jak klasa

module Pushover 
    def configure 
    .. 
    end 
end 

module MyModule 
    class Pushover 
    def blah 
     Pushover.configure 
    end 
    end 
end 

To nie działa, ponieważ wywołanie Pushover.configure kieruje do zawierającej klasy. Teraz oczywistą poprawką byłoby zmiana nazwy klasy. Jednak moduł pochodzi z klejnotu, a klasa jest zgodna z konwencją nazewnictwa wymaganą w DSL. Idealnie więc oba powinny pozostać takie same. Mógłbym także stworzyć drugą klasę pomocników i zadzwonić przez to, ale to wszystko wydaje się trochę odurzające. Moim preferowanym rozwiązaniem byłoby bezpośrednie odwołanie się do metody modułu.

Wszystkie istniejące pytania dotyczące tego obszaru wydają się ujednoznaczniać w przeciwnym kierunku - tzn. Chcą uzyskać odniesienie do klasy, a nie modułu.

Czy jest jakiś sposób, aby poinformować Ruby, że mam na myśli moduł, a nie klasę, kiedy określam Pushover?

+0

Dlaczego trzeba wymienić moduł 'Pushover' i klasę' Pushover' w innym module to samo? Wygląda na to, że prosisz o kłopoty, szczególnie w dłuższej perspektywie, jeśli musisz wziąć udział w debugowaniu lub konserwacji. –

+0

Zgadzam się. Jednak nie mam wielkiego wyboru. Dostarczam łatkę do aplikacji innej osoby, używając klejnotu kogoś innego. Jeśli zmienię nazwę klasy na MyModule :: PushoverNotifier, to "DSL", która używa tego, będzie wyglądało dziwnie. (To jest dla Klejnotu kopii zapasowej btw.). Obecnie użytkownik może zrobić "notify_by Twitter" lub "notify_by Mail". Tak więc 'notify pushover 'wydaje się logicznym rozszerzeniem, a nie' notify_by PushoverNotifier', które byłoby wyjątkiem od standardu. –

+0

Ugh. To wtedy, gdy utrzymywanie kodu staje się brzydkie, gdy jesteś w kącie z powodu czyjegoś wyboru. Czuję twój ból. –

Odpowiedz

11

Jeśli nie chcesz spojrzeć na stałe w stosunku do bieżącego zakresu, wystarczy użyć ścieżki bezwzględnej:

::Pushover.configure 
+0

Ah! Więc :: efektywnie ucieka z bieżącego zakresu. Nie w pełni to doceniam. Dzięki. –

+1

Działa dokładnie tak, jak ścieżki '/' w systemie plików. Ścieżki zaczynające się od '/' są bezwzględne (lub są względem katalogu głównego), inne są względne. W Ruby, ciągłe wyszukiwanie rozpoczyna się od bieżącego zakresu, natomiast '::' rozpoczyna się od "globalnego zasięgu" (w rzeczywistości nie ma zasięgu globalnego, zaczyna się od klasy 'Object'). –

Powiązane problemy