2009-06-15 28 views
8

của Ruby dường như không có một cơ sở cho việc xác định một bảo vệ/khối tin như vậy:Khối Riêng tư/Được bảo vệ trong Ruby?

protected do 
    def method 
    end 
end 

này sẽ được tốt đẹp so với

protected 

def method 
end 

public 

nơi bạn có thể quên "công cộng" sau các phương pháp được bảo vệ.

Có vẻ như có thể thực hiện điều này bằng cách sử dụng lập trình meta. Có ý tưởng nào không?

Trả lời

15

Vì bạn muốn nhóm theo chức năng bạn có thể khai báo tất cả các phương pháp của bạn, và sau đó khai báo những phương thức nào được bảo vệ và riêng tư bằng cách sử dụng được bảo vệ theo sau ký hiệu của phương pháp bạn muốn bảo vệ.

Lớp sau hiển thị ý tôi. Trong lớp này, tất cả các phương thức đều công khai trừ bar_protected và bar_private được khai báo là protected và private ở cuối.

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

tôi quyết định chấp nhận điều này là câu trả lời vì đây là cách Ruby được định nghĩa. Tôi đã giả định rằng metaprogramming một khối bảo vệ nên được dễ dàng, nhưng rõ ràng, nó không phải. Và, tốt hơn là không thực hiện lập trình meta cho đến khi bạn có thể xác nhận thông qua các thử nghiệm mà nó hoạt động. Tuy nhiên, nhờ Chuck để thử vấn đề :) – gsmendoza

+1

Có vẻ như tư nhân và được bảo vệ nên được khối. Tôi tự hỏi tại sao họ không. – mysmallidea

+0

Tôi thứ hai những gì @RyanHeneise đã nói - có ai có thể cung cấp một số thông tin chi tiết hơn về quy ước này không? – Noz

9

Tôi thực sự tán thành giải pháp bodnarbm và không khuyên bạn làm điều này, nhưng kể từ khi tôi không thể bỏ qua một thách thức lập trình meta, đây là một hack mà sẽ thực hiện điều này:

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

Cảm ơn! Tôi sẽ thử nó :) – gsmendoza

+0

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

Các vấn đề liên quan