Ruby1.8: 'private' doesn't give expected level of privacy

ADSENSE HERE!
The classic OOP pattern usually called encapsulation implemented in ruby with private and protected keywords methods. The distinction between API and implementation works great with both. The problem is that private doesn't hide method for inherited classes.



See the simple example below:


class A
private
def implementation
puts 'private A'
end
end

class B < A
def api
implementation
end
end

B.new.api


And we won't get exception at the last line.
The real difference between protected and private methods is more specific.
At first: implementation method can not be called like self.implementation even from class A.
class A
def api
self.implementation #exception here
end
private
def implementation
puts 'private A'
end
end

A.new.api

Seamless pure gap. You can do such call if the method would be protected. Can't imagine the case when this limitation is useful.

The second difference is a bit esoteric. Two instances of the same class can access protected methods of each other but not private methods.

class A
def api(another) #suppose to receive an instance of a
implementation == another.implementation
end
protected
def implementation
puts 'private A'
end
end
A.new.api(A.new)

Fine for protected but fail for private. Well, this kind of protection do not make a real because of it's rareness.



You might do any decision on the points above.
My conclusion is to not use private at all, because it doesn't give the level of privacy that I expect. private is not suitable for such an extremely dynamic language as Ruby.
ADSENSE HERE!

3 comments:

  1. The way we are using private in our team is to give hints to the programmer who will refactor the class later. Private methods: Go crazy. Public methods: Expect lots of tests to break.

    ReplyDelete
  2. Yes, it's well practice. But I preffer to always use protected instead of private.

    ReplyDelete
  3. The `private' implementation makes sense when you take into account that in Ruby you don't "call methods", you "send messages" to other objects. That's why it doesn't matter if the other object has the same type as the one that sends the message (technically, it may not even be true, if the other objects has undergone some monkey patching). Although I consider the fact that you can't send private messages to self to be a bug -- Ruby should "know" that self is self :)

    ReplyDelete

Komen dong, tapi yang sopan dan tidak spam ya

Arsip Blog

Copyright © Spesial Unik. All rights reserved. Template by CB. Theme Framework: Responsive Design