views:

132

answers:

3

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?

+6  A: 

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)
Ionuț G. Stan
Can you provide a citation?
John Saunders
I'm still searching for it.
Ionuț G. Stan
"Private" in this sense seems more truly modular. I hope other languages pick up similar functionality.
Imagist
1. This is the same in Java. 2. I bet this "never" means "never unless you use some internal API that can circumvent this".
Aaron Digulla
@Aaron, I may have understood it wrong, but it's no the same in Java. I'll post a comparison example.
Ionuț G. Stan
Ionut, Can you say anything about how program design changes in ruby because of this property? I am happy to know that there's a mainstream language with the feature, but I'm most curious about the impact of this language choice on how we write software.
Carl Manaster
@Carl, honestly, I don't have too much experience in Ruby, so I can't really give a good insight. The only thing I can think of is that this feature allows far more fine-grained control over the source of side effects. An object internal structure isn't at the mercy of another object, even if they are instances of the same class, which is a good thing. I don't know any idioms or patterns supported by this feature though.
Ionuț G. Stan
This is the best answer given, so I'm accepting it, although I'm still really curious about the impact on program design and I wish someone had had an answer to that part of the question.
Carl Manaster
A: 

You could implement this in C# by having some method capable of walking the stack and checking which object the caller is, and throwing an exception if it's not the current class. I don't know why you would want to, but I thought I'd throw it out there.

Max Schmeling
Clarification: this thing should be done at compile time. It is useless at runtime.
EFraim
Wtf did this get downvoted for? It's a valid answer...
Max Schmeling
No, it's a pervertion. Incuring terrible runtime overhead, and using absolutely incorrect method.
EFraim
A: 

The main reason why no language has support for this at the semantic level is that the various needs are too different to find a common denominator that is big enough for such a feature. Data hiding is bad enough as it is, and it gets only worse when you need even more fine grained control.

There would be advantages to such a language, for example, you could mark certain data as private for anyone but the object which created it (passwords would be a great example: Not even code running in the same application could read them).

Unfortunately, this "protection" would be superficial since at the assembler level, the protection wouldn't exist. In order to be efficient, the hardware would need to support it. In this case, probably at the level of a single byte in RAM. That would make such an application extremely secure and painfully slow.

In the real world, you'll find this in the TPM chip on your mainboard and, in a very coarse form, with the MMU tables of the CPU. But that's at a 4K page level, not at a byte level. There are libraries to handle both but that doesn't count as "language support" IMO.

Java has something like this in form of the Security API. You must wrap the code in question in a guardian which asks the current SecuityManager whether access is allowed or not.

In Python, you can achieve something similar with decorators (for methods and functions) or by implementing __setattr__ and __getattr__ for field access.

Aaron Digulla
Your analysis is valid in a sense, but you seem to be confusing "data encapsulation" with "data security". The public, protected, and private modifiers in OOP languages aren't meant to "secure" data, but rather to encapsulate data in a class, and "protect" it from alteration by other classes. The modifiers aren't meant to "protect" data in the information security sense.
mipadi
What would be the point of such a feature if not security? For data encapsulation, "private" is enough because you can always wrap a single field in a class to protect access to it from other instances of the same class.
Aaron Digulla