2013-09-08 14 views
13

To pytanie jest bezpośrednio związane z this one. Próbowałem jednak rozbić to na podstawowy problem i nie chciałem wprowadzać więcej tekstu do drugiego pola pytania. A więc tutaj:Jak przedkładać metody klasy

Wiem, że mogę dołączyć metody klas przez rozszerzenie modułu ClassMethods i włączenie go za pomocą haka Module # include. Ale czy mogę zrobić to samo z prependem? Oto mój przykład:

klasy Foo:

class Foo 
    def self.bar 
    'Base Bar!' 
    end 
end 

klasy Rozszerzenia:

module Extensions 
    module ClassMethods 
    def bar 
     'Extended Bar!' 
    end 
    end 

    def self.prepended(base) 
    base.extend(ClassMethods) 
    end 
end 
# prepend the extension 
Foo.send(:prepend, Extensions) 

klasa FooE:

require './Foo' 

class FooE < Foo 
end 

i prosty startscript:

require 'pry' 
require './FooE' 
require './Extensions' 

puts FooE.bar 

Po uruchomieniu skryptu nie otrzymuję Extended Bar!, jak się spodziewam, ale raczej Base Bar!. Co muszę zmienić, aby działać poprawnie?

Odpowiedz

18

Problemem jest to, że nawet jeśli jesteś poprzedzenie moduł, ClassMethods wciąż się extend ED Można to zrobić, aby dostać to, czego chcesz.

module Extensions 
    module ClassMethods 
    def bar 
     'Extended Bar!' 
    end 
    end 

    def self.prepended(base) 
    class << base 
     prepend ClassMethods 
    end 
    end 
end 

Należy pamiętać, że sama mogłaby Extensions być dołączany na początku lub zawarte w Foo. Ważną częścią jest przedrostek ClassMethods.

+0

Very nice! Wielkie dzięki. Oczywiście nie wiedziałem, co się dzieje. – Nessuno

+0

Świetnie, dzięki ... – Fabio

24

Prostsza wersja:

module Extensions 
    def bar 
    'Extended Bar!' 
    end 
end 

Foo.singleton_class.prepend Extensions 
+1

Dzięki, takie proste, gdy widzisz ... – 244an