2009-12-13 14 views
12

Mam klasę ze stałą zdefiniowaną dla niej. Następnie mam zdefiniowaną metodę klasy, która uzyskuje dostęp do tej stałej klasy. To działa dobrze. Przykład:(W języku Ruby), zezwalając na stosowanie metod klasy mieszanej w celu uzyskania stałych klas

#! /usr/bin/env ruby 

class NonInstantiableClass 
    Const = "hello, world!" 
    class << self 
     def shout_my_constant 
      puts Const.upcase 
      end 
     end 
    end 

NonInstantiableClass.shout_my_constant 

Mój problem pojawia się przy próbie przenieść tę metodę klasy się do modułu zewnętrznego, tak jak poniżej:

#! /usr/bin/env ruby 

module CommonMethods 
    def shout_my_constant 
     puts Const.upcase 
     end 
    end 

class NonInstantiableClass 
    Const = "hello, world!" 
    class << self 
     include CommonMethods 
     end 
    end 

NonInstantiableClass.shout_my_constant 

Ruby interpretuje sposób jak żądania stały z modułu, zamiast klasa:

line 5:in `shout_my_constant': uninitialized constant CommonMethods::Const (NameError) 

Jakie magiczne sztuczki powinniście mieć, aby metoda uzyskała dostęp do stałej klasy? Wielkie dzięki.

Odpowiedz

14

To wydaje się działać:

#! /usr/bin/env ruby 

module CommonMethods 
    def shout_my_constant 
     puts self::Const.upcase 
    end 
end 

class NonInstantiableClass 
    Const = "hello, world!" 
    class << self 
     include CommonMethods 
    end 
end 

NonInstantiableClass.shout_my_constant 

HTH

+0

Cóż, to rozwiązuje problem. Musiałem jeszcze doświadczyć składni :: :). – jameshfisher

+0

Nie przestawaj już czytać. Przeczytaj poniżej odpowiedź johannes. – Sebastian

9

jest problem, jeśli tylko napisać Const jest oceniana na czas tworzenia modułu. Musisz użyć Module#const_get zamiast tego: const_get(:Const). Jest to oceniane w czasie wykonywania, gdy metoda jest wykonywana. Tak dzieje się w twojej klasie, a nie w twoim module.

+0

Dzięki! To była metoda, której szukałem bez powodzenia. – jameshfisher

12

Warto chyba zauważyć, że nie ma potrzeby dołączania modułów do metaclass.

class NonInstantiableClass 
    Const = "hello, world!" 
    class << self 
     include CommonMethods 
    end 
end 

Ruby ma extend słowa kluczowego, które skutecznie dodaje interfejs modułów do klasy, na przykład

class NonInstantiableClass 
    Const = "hello, world!" 
    extend CommonMethods 
end 

Trzeba jeszcze, aby zapewnić sobie przedstawieniu właściwej stałej przy użyciu self::Const lub const_get, ale extend <module> jest lepszym sposobem na dodanie tych metod do klasy.

+0

Jeszcze jeden pomocny komentarz. Nauczyłem się trzech rzeczy od zadawania jednego pytania. – jameshfisher

Powiązane problemy