2011-11-02 15 views
6

Muszę zabraknąć czegoś o tym, jak ludzie robią to w Ruby.W jaki sposób jeden dostęp chroni metody klasy przed metodami instancji w Ruby?

Jeśli '#protected' jest komentarzem otrzymujemy:
w 'co': protected metoda 'Zoop' wezwał do Foo: Klasa (NoMethodError)

Czy istnieje lepszy sposób, aby zbliżyć metod klasy chronione?

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'" 

Chciałbym Zoop być chronione lub prywatnych (nie wywołujący „Foo.zoop”), ale do tej pory nie mogę wydawać się znaleźć elegancki sposób.

+0

Czy istnieje założenie, że instancje klasy powinny mieć bardziej intymny dostęp do pojedynczych metod klasy niż inne obiekty? –

+0

Rzeczywiście. I dobrze powiedziane. –

Odpowiedz

2

Po dalszej dyskusji z rue a drbrain: Ruby-lang, okazuje się, że mój impuls, aby zaoszczędzić pamięć umieszczanie funkcji użyteczności na poziomie klasy było niewłaściwie umieszczone.

W języku Ruby metody instancji pozostają zawieszone w klasie mimo to, a odpowiedź brzmi następująco: funkcje narzędzia na poziomie instancji są prywatne.

Podsumowując, funkcja narzędzie, które jest dostępne tylko metodami np:

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

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

Dla funkcji użytkowej, która musi być wywołana z instancji i klasy metod, moduł zagnieżdżona wydawał się być popularne podejście:

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

Nie ma większego znaczenia, aby metody były prywatne lub chronione w Ruby, ponieważ można po prostu wywołać metodę send(), aby ominąć je.

Jeśli chcesz Zoop pozostać chronione, wykorzystanie send() tak:

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