2009-06-15 2 views
8

Рубин не кажется, есть средство для определения защищенного/закрытый блок, как так:Частный/Защищенный блок в Ruby?

protected do 
    def method 
    end 
end 

Это было бы неплохо по сравнению с

protected 

def method 
end 

public 

, где вы можете забыть «общественность» после того, как защищенные методы.

Возможно реализовать это с помощью метапрограммирования. Любые идеи как?

ответ

15

Поскольку вы хотите группировать по функциональности, вы можете объявить все свои методы, а затем объявить, какие из них защищены и закрыты, с помощью защищенных, за которыми следуют символы методов, которые вы хотите защитить, а также для частных.

Следующий класс показывает, что я имею в виду. В этом классе все методы являются общедоступными, кроме bar_protected и bar_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

+1

Кажется, что частные и защищенные должны быть блоками. Интересно, почему они не такие. – mysmallidea

+0

Я второй, что сказал @RyanHeneise, - это кто-нибудь, кто может дать более глубокое понимание этого соглашения? – Noz

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 
+0

Спасибо! Я попробую :) – gsmendoza

+0

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

Смежные вопросы