2009-06-15 18 views
8

Rubin scheint nicht eine Einrichtung zum Definieren eines geschützten/privaten Blockes wie so hat:Private/geschützte Block in Ruby?

protected do 
    def method 
    end 
end 

Dies zu

Vergleich wäre schön
protected 

def method 
end 

public 

, wo man vergessen könnte „public“ nach die geschützten Methoden.

Es scheint möglich, dies mit Metaprogrammierung zu implementieren. Irgendwelche Ideen wie?

Antwort

15

Da Sie nach Funktionalität gruppieren möchten, können Sie alle Ihre Methoden deklarieren und dann deklarieren, welche geschützt und privat sind, indem Sie protected gefolgt von den Symbolen der Methoden, die geschützt werden sollen, und derselben für private angeben.

Die folgende Klasse zeigt was ich meine. In dieser Klasse sind alle Methoden öffentlich, mit Ausnahme von bar_protected und bar_private, die am Ende als geschützt und privat deklariert werden.

class Foo 

    def bar_public 
    print "This is public" 
    end 

    def bar_protected 
    print "This is protected" 
    end 

    def bar_private 
    print "This is private" 
    end 

    def call_protected 
    bar_protected 
    end 

    def call_private 
    bar_private 
    end 

    protected :bar_protected 

    private :bar_private 

end 
+0

entschied ich mich, das akzeptieren als Antwort, denn so ist Ruby definiert. Ich nahm an, dass die Metaprogrammierung eines geschützten Blocks einfach sein sollte, aber anscheinend nicht. Und es ist besser, nicht zu metaprogrammieren, bis Sie durch Tests bestätigen können, dass es funktioniert. Immer noch, dank Chuck für das ausprobieren des Problems :) – gsmendoza

+1

Scheint wie privat und geschützt sollte Blöcke sein. Ich frage mich, warum sie nicht sind. – mysmallidea

+0

Ich zweitens was @RyanHeneise gesagt hat - kann jemand mehr Einblick in diese Konvention geben? – Noz

9

ich eigentlich bodnarbm-Lösung unterstützen und empfehlen dies nicht zu tun, aber da ich keine metaprogramming Herausforderung verzichten kann, ist hier ein Hack, dies zu erreichen:

class Module 
    def with_protected 
    alias_if_needed = lambda do |first, second| 
     alias_method first, second if instance_methods.include? second 
    end 
    metaclass = class<<self; self end 
    metaclass.module_eval {|m| alias_if_needed[:__with_protected_old__, :method_added]} 
    def self.method_added(method) 
     protected method 
     send :__with_protected_old__ if respond_to? :__with_protected_old__ 
    end 
    yield 
    metaclass.module_eval do |m| 
     remove_method :method_added 
     alias_if_needed[:method_added, :__with_protected_old__] 
    end 
    end 
end 
+0

Danke! Ich werde es ausprobieren :) – gsmendoza

+0

omg !!! 1 !! 11ONE! – rogi

Verwandte Themen