On Sat, Nov 29, 2003 at 12:40:10PM -0800, Paul Hodges wrote: : --- Larry Wall <[EMAIL PROTECTED]> wrote: : > Yes, in fact it gets a new anonymous class that is derived from its : > current class. : : Ah -- implicit adoption by the new foster parent. That's kind of neat, : but it confuses me. Does that mean you're leaning more toward allowing : undeclared properties, or just that you're still trying to give both : sides of the argument thorough consideration?
I'm not doing either of those things... :-) : Just for my vote, I want to be able to declare new properties, but : would rather not be able to accidentally set $o.ture. That's how it works. : > : or does Perl have to redesign class Foo on the : > : fly, and suddenly distribute a bar property across all Foo object : > : extant? : > : > No, the whole point of properties is that they cut across class : > lines. : > It doesn't matter whether you're flying first class or coach, you : > might acquire the property "drunk" at run time. : : The adoption mentioned above handles this, but even though properties : cut across class lines, I want to avoid those silly boo-boos. : While : : if $me.flying { : $me.drunk = "scotch"; # inebriation source : $me.dunk = true; # I do when I can : $scotch.dunk = "fig newton"; # the only acceptable value! : $newton.dunk = true; # only way I eat 'em : $scotch.drunk = true; # oops, it's all gone :( : } : : might be all well-and-good, I don't want my $newton to be able to be : set <C>$newton.drunk = true</C> by accident because in all that : pseudo-repetitive code I mistyped and the compiler let me get away with : it. Code bits like this are common enough that I want every bit of : assistance I can get. None of those are legal if the object doesn't have the property yet. Only C<but> has the power to add roles at run time. : I'd rather be able to add the .dunk and .drunk properties to classes in : which they are appropriate, even after the fact of the class : definition, but I definitely don't want that to make it possible to : drink my $newtons, nor get them inebriated. : : Am I too far over the edge here? Nope. : > But if we require declaration of properties as a kind of role, : > then the role declaration could declare whatever data structure : > it wants. In fact, a role can declare multiple attributes, which : > implies that we could conceivably have complex struct-like : > properties: : > : > return undef but error(ENOMAKESENSE, "What the heck?", 42); : > : > Under the hash view of properties, that has to be a scalar reference : > to an object, but under the role view, it can merely be a set of : > components of the undef object without a separate scalar existence. : > : > Q: Mr. Undef, are you an error object? : > A: No, but I play one on TV. : : That's beautiful, and very sensible. Where can I read up on roles a : little more? Well, it's not nearly as general as we're making it, but the inspiration for it comes in part from the "Traits" paper: http://www.cse.ogi.edu/~black/publications/TR_CSE_02-012.pdf Basically, I'm attempting to take their concept and unify it with properties, interfaces, generics, aspects, and mixins. Among other things... : But I thought properties *were* attributes, basically.... We're using "attributes" to mean instance variables defined by the class. Properties used to be considered something else, but now this role-playing I'm talking about makes them more like real attributes that happen to be added at run time. Except it doesn't modify any named class to do so, but only the anonymous class associated with the object in question. (And if there isn't an anonymous class yet, it generates one.) : Hrmm. So properties are "object" attributes unrelated to class? Unrelated to the original named class. : Ok, floundering again. Lemme think this through. : : my $x = undef but true; : : undef is a value. $x is just a joe scalar. No class, no "real" object. : I get that. We're just fiddling with the details of $x's value, and : assigning the globally available property of true to it so that : : print "foo" is $x; : : will print, even though it's value is undef. So far so good. : Now, I want to say : : my $y = undef but zippy; : : The compiler politely tells me that zippy isn't valid, and that perhaps : I should RTFM. Ok, that's good, but I really want to be able to return : a zippy undef as a response to those impertinent sub calls, so that I : can both refuse to talk to them and still have a zippy response, : effectively having my cake and eating it, too. : : Such wittiness requires a little forethought, though. : I have to predeclare what exactly I mean by "zippy", or at least : generally enough that the compiler deems it a valid comeback. : See? I'm catching up. Yep. : I'll get back to this in a bit. : : > For example, any class that wants to cache its boolean value might : > say : > : > class Fancy is Simple does true {...} : > : > Then it can recalculate its boolean value only when it needs to, : > rather than every time the object is used in a boolean context. : : Ok. So : : our property *true; : : makes sense out of class context, and can be overwritten by explicit : class values for true, but : : our property *zippy; : : would probably be a bit foolish, since there can be only one such, and : trying to redeclare it by loading two modules with that in them would : crash, but wouldn't storing the context of a property by like : recursively giving the properties some properties of their own? Is that : a can of worms we really want to open? I don't see what the problem is. Once anyone has declared *zippy, everyone has a global zippy, and it's the same global zippy everywhere. You only get separate zippys if in more than one place you say things like: our property zippy; my property zippy; Either of those declarations may be exported, however, in which case the importing modules shares the zippy, just as it would share an exported variable. : > I didn't mention it in my previous article, but roles are also a : > generalization of interfaces. That is, interfaces are a degenerate : > case of roles, when the role doesn't supply any implementation, which : > forces the class incorporating the role to supply an implementation. : > (Property roles don't fall into this category because the implied : > : > has $.bar is rw; : > : > also implies the .bar accessor to it, which is all the implementation : > it needs.) : : All I've seen on interfaces is a few lines in passing. Anyone got a : reference where I can RTFM and thin the spam to the list? :) Don't have a doc, but see Java for an example. Basically it's a clunky way of sneaking a little bit of multiple inheritance into a language that only supports single inheritance. Larry