On 2/12/06, Yiyi Hu <[EMAIL PROTECTED]> wrote: > For perl 6, > Array and Scalar are in different namespace. > So, > class A { has $.a; has @.a }; > > what will A.new.a return by default? > > An Error? or Scalar has a higher priority?
It seems to me that the best way to approach this issue is to seperate the accessor generation from the attribute declaration. To start with, in Perl 5, it is entirely possible to do this without ambiguity: package Foo; our $bar; our @bar; This is because '$bar' and '@bar' are different names. Perl 6 should follow this, and store the meta-objects which represent these attributes using different names as well, so given: class A { has $.a; has @.a }; You would find two attribute meta-objects, one keyed to '$.a' and the other to '@.a', and there is no ambiguity. Now for the accessor generation portion of this question. Accessor generation should probably take place towards the end of class construction. You need to think of class construction as a multi-step process, first the name is encountered: class A; At this point a metaclass should be created and named A. Next the body of the class should be evaluated within the context of the metaclass. As each attribute declaration is encountered, it should be converted to metaclass calls to further construct the class. So things like this: has $.a; Will translate to something like this: $::CLASS.add_attribute(Perl6::Meta::Attribute.new(:name<$.a>)); Now, when the classes body has been completely evaluated, a method should be called on the metaclass (found in the $::CLASS pseudo-lexical variable) to tell the metaclass that that class construction has been finished. This method should finish up the class construction and at this point the attribute accessors should now be generated. Now, here is my proposal for how accessor generation should be handled. I think that the metaclass (stored in the pseudo-lexical $::CLASS) should create a number of anonymous roles on the fly: role { multi method a (::CLASS $self) { ... } multi method a (::CLASS $self, Scalar $value) { ... } } role { multi method a (::CLASS $self) { ... } multi method a (::CLASS $self, Array @value) { ... } } These roles would then be added to the metaclass using the normal rules of role composition. (NOTE: I assume that ::CLASS is unbound until the role is composed into a class, I think A12 might have stated this detail) Now obviously we have a conflict in our multi-methods. S12 only states that multi methods will be compared by their long names (name + signature) to resolve ambiguity, it does not state what happens when those long names conflict. I propose that they work just as normal method conflicts do, which is that both methods are excluded and the consuming class is then required to implement that method. So now, if we follow the rules of role composition, when these two anonymous roles are added to the metaclass, there will be a conflict and class composition will fail. So the short answer is that this: class A { has $.a; has @.a }; will result in a fatal compile time error, while this: class A { has $.a; has @.a multi a ($::CLASS) { # do something here,.. I dont know what :) } }; will not fail. Hope this helps :) Stevan