Ruby doesn't seem to have a facility for defining a protected/private block like so:
protected do
def method
end
end
This would be nice compared to
protected
def method
end
public
where you might forget to "public" after the protected methods.
It seems possible to implement this using metaprogramming. Any ideas how?
protected methods can be called by any instance of the defining class or its subclasses. private methods can be called only from within the calling object. You cannot access another instance's private methods directly.
Protected methods In Ruby, a protected method (or protected message handler) can only respond to a message with an implicit/explicit receiver (object) of the same family. It also cannot respond to a message sent from outside of the protected message handler context.
A Ruby method can be:By default ALL your methods are public . Anyone can use them! But you can change this, by making a method private or protected .
Private: – When a method is declared private in Ruby, it means this method can never be called with an explicit receiver. Any time we're able to call a private method with an implicit receiver.
Since you want to group by functionality you can declare all your methods, and then declare which ones are protected and private by using protected followed by the symbols of the methods you want to be protected, and the same for private.
The following class shows what I mean. In this class all methods are public except bar_protected and bar_private which are declared protected and private at the end.
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
I actually endorse bodnarbm's solution and do not recommend doing this, but since I can't pass up a metaprogramming challenge, here's a hack that will accomplish this:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With