2009-06-15 101 views
8

紅寶石似乎並不有一個設施進行定義,像這樣一個保護/私有塊:Ruby中的私有/受保護塊?

protected do 
    def method 
    end 
end 

相比

protected 

def method 
end 

public 

,你可能會忘記「大衆」之後這將是很好的受保護的方法。

似乎可以使用元編程來實現這一點。任何想法如何?

回答

15

由於您想按功能分組,因此您可以聲明所有的方法,然後通過使用受保護的後面跟隨您想保護的方法的符號來聲明哪些是受保護和私有的,並且私有相同。

下面的課程展示了我的意思。在這個類中,除bar_protected和bar_private之外,所有方法都是公共的,它們在最後被聲明爲protected和private。

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

我決定接受這個作爲答案,因爲這是Ruby定義的方式。我假設元編程一個受保護的塊應該很容易,但顯然不是。而且,最好不要進行元編程,直到你可以通過測試確認它的工作。儘管如此,感謝查克試驗這個問題:) – gsmendoza 2009-06-17 09:01:20

+1

似乎私人和保護應該是塊。我想知道他們爲什麼不是。 – mysmallidea 2011-05-20 16:09:00

9

其實我贊同bodnarbm的解決方案,不建議這樣做,但因爲我不能放過元編程挑戰,這裏是一個黑客工具,將做到這一點:

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 
相關問題