You may find it helpful to read the ruby โโdefinition of the public, private, and protected. (Go to access control)
Ruby private is similar to secure Java. There is no Ruby equivalent for Java. EDIT:. This solution now provides a method for falsifying the Java ideal of the private in Ruby objects.
Private is defined as methods / variables that can name implicitly. This is why statements 2 and 3 fail. In other words, private limits use methods / variables for the context of the class or subclass in which they are defined. Inheritance passes private methods to subclasses and therefore can be accessed with an implicit self. (Explains why instruction 6 works.)
I think you are looking for something closer to protected. Which behaves similarly to Java accessories that are not provided with visibility (for example, public, private, protected). Changing the personal in Spy to protect all 6 of your applications. Protected methods can be called by any instance of the defining class or their subclasses. Explicitly or implicitly called self are valid statements for protected methods if the calling object is either a class of the object that answers the call or inherits from it.
class Person private attr_reader :weight end class Spy < Person protected attr_accessor :code public def test code #(1) OK: you can call a private method in self Spy.new.code
As for statement 4. You are right in considering this to avoid ambiguity. It rather protects the potential harm of a ruby โโdynamic character. This ensures that you cannot override accessors by opening the class again later. A situation that may arise, for example, by eval'ing corrupted code.
I can only guess about his design decisions that led to this behavior. For the most part, I feel that it comes down to the dynamic nature of the language.
PS If you really want to give things, the definition of java is private. Available only to the class in which it is defined, not even subclasses. You can add the self.inherited method to your classes to remove references to the methods you want to restrict access to.
Make the weight attribute inaccessible from subclasses:
class Person private attr_reader :weight def initialize @weight = 5 end def self.inherited(subclass) subclass.send :undef_method, :weight end end class Spy < Person private attr_accessor :code public def test weight end end Person.new.send(:weight)
It might make sense to replace the undef_method call with something like this:
def self.inherited(subclass) subclass.class_eval %{ def weight raise "Private method called from subclass. Access Denied" end } end
This provides a much more efficient bug and the same functionality.
Submission is necessary to call private methods for other classes. It is used only to prove that everything actually works.
Which in retrospect makes private and protected worthless. If you are really serious about protecting your methods, you will have to redefine sending to block them. The following code does this based on the private_methods object:
def send_that_blocks_private_methods(method, *args) if private_methods.include?(method.to_s) raise "Private method #{method} cannot called be called with send." else send_that_allows_private_methods(method, *args) end end alias_method :send_that_allows_private_methods, :send alias_method :send, :send_that_blocks_private_methods private :send_that_allows_private_methods
You can specify the class_variable private_methods for which you want to block access, instead of denying access to all private methods. You can also make send private, but there is legal use of the send call from outside the object.