2011-11-02 14 views
6

Mi manca qualcosa su come le persone lo fanno in Ruby.Come si accede ai metodi di classe protetti dai metodi di istanza in Ruby?

Se '#protected' non sia commentata otteniamo:
in 'cosa': metodo protetto 'Zoop' chiamato per Foo: Classe (NoMethodError)

C'è un modo migliore per avvicinarsi a metodi di classe protetti?

class Foo 
    class << self 
    #protected 
    def zoop 
     "zoop" 
    end 
    end 
    public 
    def what 
    "it is '#{self.class.zoop}'" 
    end 
    protected 
end 

a = Foo.new 
p a.what # => "it is 'zoop'" 

Vorrei zoop da proteggere o privato (nessuna chiamata 'Foo.zoop'), ma finora, non posso sembrare trovare un modo elegante.

+0

Esiste un'ipotesi sottostante secondo cui le istanze di una classe dovrebbero avere un accesso più intimo ai metodi di singleton della classe rispetto agli altri oggetti? –

+0

Infatti. E ben detto. –

risposta

2

Su ulteriori discussioni con rue: e drbrain: in Ruby-Lang, si scopre che il mio impulso per risparmiare memoria collocare le funzioni di utilità a livello di classe era fuori luogo.

In Ruby, i metodi dell'istanza si bloccano comunque sulla classe e la risposta è di andare avanti e posizionare le funzioni di utilità a livello di istanza come private.

In sintesi, una funzione di utilità a cui si accede solo con metodi di istanza:

class Foo 
    def what 
    "it is '#{zoop}'" 
    end 
    private 
    def zoop 
    "zoop" 
    end 
end 

p Foo.new.what # => "it is 'zoop'" 

Per una funzione di utilità che ha bisogno di essere chiamato da istanze di classe e metodi, un modulo nidificato sembrava essere un approccio popolare:

class Foo 
    module Util 
    def self.zoop 
     "zoop" 
    end 
    end 
    def what 
    "it is '#{Util.zoop}'" 
    end 
    class << self 
    def class_what 
     "for all time it is '#{Util.zoop}'" 
    end 
    end 
end 

p Foo.new.what # => "it is 'zoop'" 
p Foo.class_what # => "for all time it is 'zoop'" 
p Foo::Util.zoop # visible, alas 
2

Importa a malapena a rendere i metodi privati ​​o protetti in Ruby, dal momento che è possibile chiamare send() per aggirarli.

Se si desidera Zoop a rimanere protetti, uso send() in questo modo:

def what 
    "it is '#{self.class.send(:zoop)}'" 
end 
Problemi correlati