Third time's the charm...really. Please ignore the last two messages from me in favor of this one please. Sigh**2.
--- On 7/22/05 11:37 AM, Larry Wall wrote: > The problem I have with "is private" is that, while there may very > well be a trait of that name that you can interrogate, I really > want people to think of the private methods as being in a different > namespace so that there's no confusion about the fact that you can > have a private method and a public method of the same name. Er, but can you ever have a public method that begins with an underscore under your new system? If not, then there'd never be any of the overlap that you want people not to be confused about. See, now I'm confused... I get this part: > The problem with > > $?SELF.:foo() > > is that people see that as a .: operator on the foo method. and like I said, I'm not insistent on using the colon. But I would like to find a way to remove the proposed contextual magic of the leading underscore and replace it with something a bit more explicit and obvious--in both the calling syntax and the declaration syntax. So, the problem looks like this. We want to find a way to: * Define a private rw attribute named "foo" with an auto-generated non-virtual accessor. * Define a public rw attribute named "foo" with an auto-generated virtual accessor. * Call both of the accessors above with no ambiguity between the calls, even though both attributes have the same name. The proposed solution: # Define a private rw attribute with an auto-generated # non-virtual accessor. has $_foo; # Define a public rw attribute with an auto-generated # virtual accessor. has $.foo is rw; # Call both of the accessors above with no ambiguity between the calls, # even though both attributes have the same name. $?SELF._foo(); # private accessor $?SELF.foo(); # public accessor kind of sidesteps the "same name" issue by, well, not giving both the attributes the same name. Instead of two attributes both named "foo", the private one is now named "_foo". This makes the accessor calls unambiguous, but it doesn't really succeed in emphasizing the separateness of the private and public namespaces. Since my goal is to remove the "_" magic, I first have to find a way to differentiate a "private rw attribute with an auto-generated non-virtual accessor" from a "private rw attribute with no auto-generated accessor." I proposed some sort of trait for that earlier: # Define a public rw attribute with an auto-generated # virtual accessor. has $.foo is rw; # Define a private rw attribute named "foo" with an auto-generated # non-virtual accessor. has $foo is private rw; where the "private" name is up for grabs. Or it could be turned around: has private $foo; The next problem to solve is how to differentiate the calls. The colon is out because it looks like an operator. The attribute names are really both "foo", so we can't use the accessor name itself to differentiate. But both those two "foo"s are in separate namespaces, right? That's why we can have both of them in the same class. So how do we indicate the namespace separation in the call? In the spirit of the (now dead?) SUPER:: from Perl 5, this immediately springs to mind: $?SELF.foo(); # public $?SELF.PRIVATE::foo(); # private That's ugly and long, but at least it's clear. And it doesn't look like an operator, that's for sure. How about some shorter alternatives: $?SELF.OWN::foo(); $?SELF.MY::foo(); The bottom line, I think, is that if you really want private and public accessors to live in totally different namespaces, you need to explicitly namespace one or both of the calls. Name mangling isn't enough. For example, imagine this: # Define a private rw attribute named "foo" with an auto-generated # non-virtual accessor named "_foo" has $foo is private rw; # Define a public rw attribute named "foo" with an auto-generated # virtual accessor also named "foo" has $.foo is rw; $?SELF.foo(); # public $?SELF._foo(); # private A silly example, perhaps, but it does make two attributes both named "foo", one public and one private. The calls are disambiguated because the auto-generated non-virtual accessor for the private attribute has a leading underscore added to the actual attribute name--IOW, name mangling. But now look at this: # Define a private rw attribute named "foo" with an auto-generated # non-virtual accessor named "_foo" has $foo is private rw; # Define a public rw attribute named "foo" with an auto-generated # virtual accessor also named "foo" has $.foo is rw; has $._foo; # BOOM - compile-time error: method _foo() already exists method _foo { ... } # ditto "Ah ha!" you say. "Isn't that an example of the private interface interfering with the public interface?" Exactly--but AFAICT, the original proposal suffers from the same problem! # Define a private rw attribute with an auto-generated # non-virtual accessor. has $_foo; # Define a public rw attribute with an auto-generated # virtual accessor. has $.foo is rw; has $._foo; # BOOM - compile-time error: method _foo() already exists method _foo { ... } # ditto The point is, if you really want to the namespaces of the public and private attribute accessors to be entirely isolated from each other, then you need to use some sort of real namespacing system. Name mangling with standard identifier characters is not adequate. -John