
Submitted by Tomasz Wegrzanowski (Fri Oct 06 21:21:14 UTC 2006)
This definition is very problematic. Nowhere else in the language a concept like "a class in which given method was defined" occurs - methods are normally associated with objects, and for all other operations it doesn't matter in what way they were defined.
Likewise, concept like "class of self in caller" doesn't occur anywhere else in Ruby. self is simply some object, so its class should not matter. Caller self isn't even directly involved here, as protected visibility is relevant only for "explicit receiver" method calls.
Protected visibility cannot be currently reflected about, as there is no way to ask an object in which classes where its methods defined - if Foo has protected method #xyzzy, and Bar < Foo has protected #xyzzy, we have no way of learning whether Bar#xyzzy is simply Foo#xyzzy (and can be called from within instance of Foo), or redefined Bar#xyzzy (and can only be called from within instance of Bar).
Protected method calls cannot be delegated. To delegate we first need information on caller's context, that is at least self in the caller. Then self.instance_eval { obj.protected_send(...) } could work. Concept of "self in the caller" is found nowhere else in Ruby.
Even if full set of operations needed to support "protected" was provided, metaprogramming would be significantly more difficult. In practice delegation and other metaprogramming is most likely to disregard correct handling of "protected" visibility, and those few programs that use "protected" are likely to encounter bugs.
Remove protected, protected_methods, protected_instance_methods, protected_method_defined? methods from Module class, and anywhere else it is present.
Cost of full support would be significant. Concepts like "class where method was defined" and "class of self in caller" would have to be supported thoughout the language, third version of "send" would be required (in addition to private funcall and public send), and metaprogramming would become significantly more complex to support "protected" correctly.
"protected" is defined in terms of relation between two classes (class of self in caller and class where method was defined), neither of which is a class of the object in question. Such visibility makes sense in class-centric style of programming (like Java or C++), and adequate support for it would necessarily change currently very object-centric Ruby into a more class-centric language.
If "protected" was widely used and was considered highly valuable, these changed could have been worthwhile. In reality, protected is rarely used, and when it is, it usually has small utility and can be easily replaced by other constructs like asking objects about their types. Significantly changing the language only to keep "protected" doesn't seem to be a good trade-off.
Keeping current situation of having "protected" visibility in Ruby without adequate support from rest of the language would ensure full backwards-compatibility, however programs that use protected would behave inconsistently when used together with many solutions based on metaprogramming, so "protected", even if kept, would most likely stay virtually unused.
Because protected is used very rarely, backwards compatibility would be broken for very few programs. Because of the minor backwards incompatibility, it's best to remove "protected" when moving to Ruby 2.
I haven't tested it, but it looks like it works, and make test returns "test succeeded".

| Comments | Current voting | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|


RCRchive copyright © David Alan Black, 2003-2005.
Powered by Ruby on Rails.
Proper message delegation functionality might solve the problems at least in part. Maybe the one with "private" visibility as well.
-matz.
It found out that Rails uses protected extensively. So, your assumption that "protected is rarely used" is not true. Even though it could be replaced by other features (or visibilities), we have to address that anyhow.
-matz.