Search code examples
language-agnosticaccess-levels

Is there a language with object-based access levels?


A common misconception about access level in Java, C#, C++ and PHP is that it applies to objects rather than classes. That is, that (say) an object of class X can't see another X's private members. In fact, of course, access level is class-based and one X object can effortlessly refer to the private members of another.

Does there exist a language with object-based access levels? Are they instead of, or in addition to, class-based access? What impact does this feature have on program design?


Solution

  • Ruby has object-based access level. Here's a citation from Programming Ruby:

    The difference between "protected" and "private" is fairly subtle, and is different in Ruby than in most common OO languages. If a method is protected, it may be called by any instance of the defining class or its subclasses. If a method is private, it may be called only within the context of the calling object---it is never possible to access another object's private methods directly, even if the object is of the same class as the caller.

    And here's the source: http://whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4

    Example difference between Java and Ruby

    Java

    public class Main {
        public static void main(String[] args) {
            Main.A a1 = new A();
            Main.A a2 = new A();
    
            System.out.println(a1.foo(a2));
        }
    
        static class A
        {
            public String foo(A other_a)
            {
                return other_a.bar();
            }
    
            private String bar()
            {
                return "bar is private";
            }
        }
    }
    
    // Outputs
    // "bar is private"
    

    Ruby

    class A
      def foo other_a
        other_a.bar
      end
    
      private
      def bar
        "bar is private"
      end
    end
    
    a1 = A.new
    a2 = A.new
    
    puts a1.foo(a2)
    
    # outputs something like
    # in `foo': private method `bar' called for #<A:0x2ce9f44> (NoMethodError)