2017-02-04 8 views
0

So sagen, ich habe diese Klasse:Gibt es `def self.method_name` und` def method_name` in einer Methode zu verkürzen?

class This 
    def a(that) 
    puts that 
    end 

    def self.b(that) 
    puts that 
    end 
end 

This.b("Hello!") # => passes 
This.a("Hello!") # => fails 

the_class = This.new() 
the_class.b("Hello!") # => fails 
the_class.a("Hello!") # => passes 

Gibt es eine Möglichkeit diese beiden Methoden in einem Verfahren zu verkürzen, die in der Lage ist, auf einem nicht initialisierten Objekt aufgerufen werden und ist in der Lage auf einem bereits initialisiert aufgerufen werden Eins, oder muss ich immer zweimal eine Methode schreiben?

+0

Was meinen Sie mit nicht initialisiertem Objekt? –

+0

Ich meine, dass ich 'the_class = This.new()' nicht gemacht habe. Ich kenne den richtigen Begriff dafür nicht, sorry! –

Antwort

6

Sie können die Funktionalität in ein Modul und beide extend und include es extrahieren.

module A 
    def a(that) 
    puts that 
    end 
end 

class This 
    include A # defines instance methods 
    extend A # defines class methods 
end 

This.a("foo") # => "foo" 
This.new.a("foo") # => "foo" 

Obwohl ich denke, dass es sowohl entweder include oder extend und nicht mehr üblich ist. Der Grund dafür ist, dass Instanzmethoden oft vom Instanzstatus abhängen, während Klassenmethoden dies nicht tun. Wenn Sie eine Instanz haben This.new und wollen eine Klasse-Methode aufrufen, können Sie .class heißt This.new.class.a

+1

Das OP hat effektiv gefragt, ob eine einzelne Methode als Empfänger entweder eine Klasse oder eine Instanz einer Klasse haben kann. Du hast das nicht beantwortet. Es scheint mir, dass Ihr Hauptpunkt darin besteht, dass Sie das simulieren könnten, indem Sie zwei Methoden mit demselben Namen erstellen, eine Klassenmethode, die andere eine Instanzmethode. Die Verwendung von 'include' und' extend' mit einem Modul ist nur eine bequeme Möglichkeit, dies zu tun. –

+0

Danke! Ich schätze die Hilfe sehr! –

1

Der folgende Code einige metaprogramming Tricks, um Auto Kopie über alle Klassenmethoden zu Instanzen dieser Klasse verwendet.

module AutoAddMethods 

    def singleton_method_added(symbol) 
    define_method(symbol, method(symbol).to_proc) 
    end 

end 

class Foo 
    extend AutoAddMethods 
    @bar = 39 

    def initialize 
    @bar = 42 
    end 

    def test_one # Only added as an instance method. 
    puts "One #{@bar.inspect}" 
    end 

    def self.test_two # Added as both an instance and class method. 
    puts "Two #{@bar.inspect}" 
    end 

end 

i = Foo.new 
i.test_one 
i.test_two 

Foo.test_two 

Und hier ist mein Testlauf Ausgang:

One 42 
Two 39 
Two 39 

Die test_two Methode ist aufrufbar sowohl von der Klasse und ihre Instanzen. Es läuft wie in der Klasse.

+0

Dies ist ein handlicher Code, den ich definitiv in meinen Projekten verwenden werde! –