2010-07-28 21 views
19

È possibile dichiarare metodi statici in un modulo in ruby?Metodi statici nei moduli rubino?

module Software 
    def self.exit 
    puts "exited" 
    end 
end 

class Windows 
    include Software 

    def self.start 
    puts "started" 
    self.exit 
    end 
end 

Windows.start 

L'esempio precedente non verrà stampato "chiuso".

È possibile avere solo i metodi di istanza in un modulo?

risposta

29

Definire il modulo simili (cioè fare exit un metodo di istanza nel modulo):

module Software 
    def exit 
    puts "exited" 
    end 
end 

e quindi utilizzare extend anziché include

class Windows 
    extend Software 
    # your self.start method as in the question 
end 

In uso:

irb(main):016:0> Windows.start 
started 
exited 
=> nil 

Ex planation

obj.extend(module, ...) aggiunge obj i metodi di istanza da ciascun modulo dato come parametro

... quindi quando usato nel contesto di una definizione di classe (con la classe stessa come il ricevitore) i metodi diventano metodi di classe.

0

E 'possibile includere metodi statici in un modulo:

module Software 

    def self.exit 
    puts "exited" 

    end 
end 

Software.exit 

L'esecuzione di questo stampe 'usciti' come previsto.

+0

ma devo includere questo modulo all'interno della classe per l'utilizzo del metodo statico? causa include include solo i metodi di istanza da un modulo non statico? –

+0

Ah, non sono sicuro su quello. Una semplice soluzione sarebbe semplicemente chiamare "Software.exit" all'interno della classe Windows e sbarazzarsi della parte "include software" (non la soluzione più elegante, ma al di fuori dello scopo di questa domanda come attualmente proposto). –

2

Due cose devono cambiare per essere in grado di chiamare Windows.exit:

  1. Software#exit deve essere un metodo di istanza
  2. Windows esigenze di extendSoftware, non include esso.

Questo perché extend ing un altro modulo mette i metodi di istanza del modulo come classe metodi del modulo corrente, mentre include ing un modulo mette i metodi come nuovi metodi di istanza.

module Software 
    def exit 
     puts "exited" 
    end 
end 

class Windows 
    extend Software 

    def self.start 
     puts "started" 
     self.exit 
    end 

end 

Windows.start 

uscita è:

 
started 
exited 
12

Metti la tua metodi di classe in un modulo nidificato, e quindi sovrascrivere il "incluso" gancio. Questo hook è chiamato ogni volta che il tuo modulo è incluso.All'interno del gancio, aggiungere i metodi della classe a chi ha fatto la comprendono:

module Foo 

    def self.included(o) 
    o.extend(ClassMethods) 
    end 

    module ClassMethods 

    def foo 
     'foo' 
    end 

    end 

end 

Ora tutte le classi tra cui Foo ottiene un metodo di classe di nome foo:

class MyClass 
    include Foo 
end 

p MyClass.foo # "foo" 

Eventuali metodi non-classe possono essere definiti in Foo come di solito.

+0

(accanto: è MyClass.foo) Questo approccio ha il vantaggio di poter aggiungere anche funzioni non statiche. – Baju

+0

@Baju, o '::' o '.' ci lavora, ma suppongo che' .' sia preferito. Ho modificato l'esempio. Grazie per la segnalazione. –

+0

-1. Yuck, questo è completamente inutile. Usa semplicemente 'extend' invece di' include'. –