Re: RFC 254 (v1) Class Collections: Provide the ability to overload classes
I haven't (and won't) have time to go into this in detail :-( I feel that this proposal is solving the wrong problem. The issue is that the original Forest and Frog (or DBI and DBI::st) classes are not *designed* for user-definable Frogs (DBI::st's). If that functionality is widely needed, the Forest should be redesigned with *configurable* Frogs. But even if you can't redesign the forest, Perl still makes it easy to impose a Japanese accent on Frogs wherever you need to: my $forest = Forest-new(); if (can_see_Mt_Fuji()) { local *Frog::speak = sub { "kerokero" }; # or: # local *Frog::speak = \Frog::Japanese::speak; print $forest-make_noise();# "kerokero" } print $forest-make_noise();# "ribbit-ribbit" Damian
Re: RFC 265 (v1) Interface polymorphism considered lovely
Thanks for getting this RFC together, Piers. A few comments: * I suggest you remove my alternative C:must(Foo) suggestion. It's too ugly to live, inless you just want to use it as a scare tactic to encourage Larry to chose the Cinterface syntax instead ;-) * The new Cinterface keyword would be unnecessary if *package specifications* could take attributes: interface Fetcher; would then become: package Fetcher : interface; * There's also no need to distinguish Cuse base and Cuse interface, since you've previously distinguished them by keyword. I would suggest that either Cuse base be used for both types of inheritance, or else the definition of an interface specification just be a regular Cpackage. * Interfaces will also need to honour Cuse delegation (RFC 193), which provides yet another way of *not* actually specifying a method, yet still having it callable. * The Cuse deferred pragma seems unnecessary, as it is sufficient to *declare* the autoloaded method, rather than *define* it. That is: use deferred 'rollover'; is really just: sub rollover; BTW, this trick already works in Perl 5 (for making Ccan acknowledge autoloaded methods). Damian
Re: RFC 188 (v2) Objects : Private keys and methods
The problem with specifying them as attributes is that I do not believe there is any way (or even any proposed way) of applying attributes to a hash entrie or a hash slice, nor is there any way of *retrospectively* applying an attribute to a hash that has already been declared elsewhere. Damian
Re: RFC - Interpolation of method calls
my $weather = new Schwern::Example; print "Today's weather will be $weather-{temp} degrees and sunny."; print "And tomorrow we'll be expecting ", $weather-forecast; You are wicked and wrong to have broken inside and peeked at the implementation and then relied upon it. I think the issue is: *what* tempted them to be so wicked and wrong. It is the fact that iniquitous direct access interpolated easily, whereas virtuous accessor access didn't. Perhaps this RFC should be subtitled: "Ne nos inducas in tentationem..." :-) Damian
Re: RFC 218 (v1) Cmy Dog $spot is just an assertion
Piers wrote: I'm kind of tempted to look at adding another pragma to go with 'use base' along the lines of: use implements 'Interface'; Which is almost entirely like Cuse base 'Interface' but with 'Interface' consisting of nothing but: package Interface; sub virtual_method; sub virtual_method2 (#prototype); ... 1; You and I must have been separated at birth, Piers. Here's what I wrote to Nat just yesterday: There would be an Cinterface pragma or keyword (let's go with keyword) that creates pseudo-packages with which lexicals can be typed. interface Fetcher; sub fetch; Interface specifications can only contain subroutine (method) declarations, which describe what behaviours the interface requires. Lexicals typed into interfaces (as opposed to packages) only require that the objects assigned to them can satisfy the interface. I.e. they don't care about the class of the object, only what is Ccan do. my Fetcher $x; my Dog $spot; my NetSnarfer $z; $x = $z;# ok because $z can fetch $x = $spot; # ok because $spot can fetch $x-fetch();# ok because Fetcher-can('fetch') $x-bark(); # not ok because ! Fetcher-can('bark') Interfaces might also act like pure abstract base classes when inherited, so that: package Dog; use base 'Fetcher'; would cause a compile-time error if Dog failed to actually provide a Cfetch method. If you'd like to run with it, be my guest (but check with Nat first, in case he wants it). Damian
Re: RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors
=head2 The CBUILD method =head3 The CREBUILD method Hey! You left out the alternative names NEW / RENEW and BLESS / REBLESS that we all like! :-( Oops. You're correct. I will rectify that. Damian
Re: RFC 218 (v1) Cmy Dog $spot is just an assertion
I was hoping Damian would be able to suggest a Perlish way of handling typechecking and polymorphism. If you mean static typechecking, then it is the natural enemy of polymorphism. Either you give up interface polymorphism (a grievous loss) or you give up static type-checking. Interface polymorphism leads to a proliferation of pointless classes. Actually, it's inheritance polymorphism that proliferates pretend classes like Pet. Perhaps instead of using inheritance for this, just have "implements" and formal interfaces. Then associate a variable with an interface instead of an object type. package Cat implements Pet; package Dog implements Pet; my Pet $foo; $foo-feed(); Not bad. Though I'd suggest a pragma: package Cat; use interface 'Pet'; my Pet $foo; $foo-feed(); Alternatively, one might imagine an attribute C:must that tells a variable that anything assigned to it must provide certain methods: my $foo : must(feed water play poop); $foo = Manager-new(); # die "Manager object can't play". An interface then becomes an alias for a particular Cmust: use attr_alias Pet = qw(feed water play poop); my $foo : must(Pet) Not sure which I like better. :-) Damian
Re: Draft RFC: my Dog $spot is just an assertion
Piers wrote: The behaviour of the my Dog $spot syntax should simply be an assertion of the invariant: (!defined($spot) || (ref($spot) $spot-isa('Dog))) (!defined($spot) || (ref($spot) $spot-isa('Dog'))) Otherwise, AMEN! Damian
Re: RFC 200 (v1) Objects: Revamp tie to support extensibility (Massive tie changes)
Also notice that I suggested the TIE be called as a method, so that it can be inherited if necessary (maybe you had that idea already???) The tie *can* currently be inherited. Yes, I was aware. It's just that you wrote: tie Some::Class $foo, @args; would produce: TIE('SCALAR', 'Some::Class', @args); and I was concerned that we were planning to remove the polymorphic dispatch. (You may have to cut me some slack over the next few days if I say stupid things or jump to unwarranted conclusions -- I am very ill and my brain is not functioning properly %-) Damian
Re: RFC 188 (v1) Objects : Private keys and methods
print keys %hash, "\n"; exists $hash{key}{subkey}; print keys %hash, "\n"; Or did that get fixed when I wasn't looking? No, the - operator has not been changed to do lazy evaluation. That's not required. All that is necessary is for Cexists nodes in the op tree to propagate a special non-autovivifying context to subordinate nodes. E.g. exists $hash{key}{subkey} exists \ entry / \ entry "subkey" / \ %hash "key" Is preprocessed to: exists \ entry(na) / \ entry(na) "subkey" / \ %hash(na) "key" which prevents %hash from autovivifying, which causes the left-most branch to fail (without autovivifying) when asked for "key", which in turn causes the entire exists to fail without autovivifying. I just don't like reading "exists causes autovivification" when it doesn't. Sorry, I was being philosophically sloppy. A call to Cexists can *result* in autovivification (of something), though it does not itself *cause* autovivification. ;-) Damian
Re: RFC 188 (v1) Objects : Private keys and methods
Why can't we just apply the same warnings on hashes as we do on variables in Perl? Maybe a new lexical pragma: no autoviv; # any autovivification carps (not just # hashes) no autoviv 'HASH'; # no new keys may spring into existence on # any hash from this point forward I don't appose these, but I don't think they solve the problem. For a start they're compile-time, not run-time. no autoviv '%hash'; # same but for a specific hash no autoviv '@array';# same but for a specific array These won't work, since most of the hashes were interested in controlling autovivification on are anonymous (blessed) ones. Regardless, I feel that "no autovivification" and "private-ization" are orthogonal and should be treated as such in the languge. private @person{'fname','lname'}; # make these private freeze %person; # no new keys But that's two keywords rather than one (and the second keyword isn't that great for those people who already use FreezeThaw ;-) I think that would prove annoying. Though I certainly don't oppose some separate method to shut off autovivification (which Cprivate would then be considered to call automatically). P.S. BTW, I used Text::Autoformat for the first time on this very email. Thanks Damian! You're most welcome. I note that you didn't use it on the P.S. itself, as Autoformat would have given you: P.S. BTW, I used Text::Autoformat for the first time on this very email. Thanks Damian! As, indeed, it just did! ;-) Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
When you want to turn off an inherited delegation in an ISA situation? Um, I don't think I understand the question. I'm confused by the question, too. Delegation is not inherited. Any module you inherit from you won't use for delegation, AFAIK. They're two different beasts. But from outside the class, you can't tell whether a method was inherited or delegated. Derived classes inherit whatever behaviour the base class provides (method dispatch to ancestors or method delegation to attributes). If your base class delegates calls to Cdelmeth, you can prevent that delegation by defining a Cdelmeth method in the derived class. Is that what you meant? Damian
Re: RFC 189 (v1) Objects : Hierarchical calls to initializersanddestructors
Given that is happens when bless is called and that all other builtin methods are anmed after what is being called, not what it is being used for, then I would say that it should be called BLESS for consistancy reason. this may seem confusing because you are thinking of one particular use that you have in mind for this, but in a generic sense it is a method that is called when bless is called. To me this points out the flaw in the entire naming scheme, not in my dissent :-) I would much prefer to see: PRINT become PRINTINGor ONPRINT PRINTF become PRINTFING or ONPRINTF DESTROY become DESTROYING or ONDESTROY BLESS be BLESSINGor ONBLESS I realize this won't happen, but one can dream. As it is, I intend to propose BUILD and REBUILD as the initializer names, and mention BLESS/REBLESS as popular alternatives. Ah, well, if worst comes to worst I can always (under RFC 128) write: sub on (""subname, subbody) { *{caller()."::$name"} = $subbody }; on BLESS { ... } on PRINT { ... } on DESTROY { ... } :-) Damian
Re: RFC 189 (v1) Objects : Hierarchical calls to initializersanddestructors
Damian, I think it would be worth at least mentioning BLESS and REBLESS in an "Alternative Names" section in the RFC. Enough people have voiced concerns over this that I think these two are worth putting in there. As I mentioned in another message, I'll be doing that. Then Larry can make the call. As always. Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
PRL One powerful application of delegation is as a replacement for PRL inheritance where the internals of a prospective base class are PRL inaccessible or inconvenient, or the base class was not designed PRL to be inherited and yet it must be. isn't this a HAS_A type of relationship? Yep. i have plenty of these in my new project and it is a pain. Yep. Hence this RFC. PRL use Class::Delegation shouldn't that be use delegation? i think you have a cut and paste error. You're correct. Many thanks. (That's what I get for pre-testing all the code in my RFCs! ;-) PRL in = [qw( getline getlines getc ungetc eof read sysread PRLinput_record_separator input_line_number )], what about a way of delegating ALL the methods of an object? any way to signify that? in = 'ALL', will look up all current methods (maybe tagged?) from the class 'in' and handle that. then you don't have to update all the delegation calls each time the 'in' object changes. Specifying Cin = [] does that. See the description of "catch-alls" below the bit you've quoted. Damian
Re: RFC 188 (v1) Objects : Private keys and methods
private $self-{data} = $derdata; should be $derdatum here? Yes. Thanks. Damian
Re: RFC 189 (v1) Objects : Hierarchical calls to initializers and destructors
I'm still not totally convinced that its so horrid to make the File::LockAndKey DESTROY call $self-SUPER::DESTROY manually... Believe me, it is in a large, deep, and/or MI hierarchy! but it does break encapsulation. Exactly. If you can figure a way out of the dilema I proposed above, I suppose this makes sense. Easy. Don't let File::Lock::Mac inherit from File::Lock. Have it *delegate* to File::Lock instead. See my forthcoming Cuse delegation RFC. Damian
Re: RFC 189 (v1) Objects : Hierarchical calls to initializers anddestructors
The "multiple inheritance paths" one is good. I like that part a lot. But the rest makes me really nervous if there's no way to override or change it. There is. I'll try and get the Cuse delegation RFC out today. One thing nobody's brought up is this: What if you decide you want the standard Perl 5 bless behavior, and you want to tweak the order of calls. So, you don't define a SETUP. BUT, the author of a module you're inheriting from defined a SETUP, not to your knowledge? This gets called automatically by bless(), with no way to override it, either making you manually undo it all or decide not to subclass it anymore. This is bad. Delegation support will make "not subclassing" it trivial. Damian
Re: RFC 189 (v1) Objects : Hierarchical calls to initializers and destructors
Also, its not entirely clear why method chaining is desired only for constructor and destructors. What about every other method? Constructors and destructors are special. They're not about *doing* something; they're about *being* (or not being) something. A "doing" method *may* wish to make the object do everything its hierarchy allows it to do: that's why I proposed CNEXT. A "being" method *must* make the object be everything its hierarchy requires it to be: that's why I proposed hierarchical constructors and destructors. Damian
Re: RFC 189 (v1) Objects : Hierarchical calls to initializers anddestructors
What happens on reblessing? An excellent question, and one that has been exercising my mind for some time now. I have come to the conclusion that a reblessing must either: * invoke the old class's DESTROY(s) and then invoke the new class's SETUP(s), or * invoke some other hierarchy of automagic methods (REFIT? RESHAPE? MORPH? TRANSMOGRIFY?), or * do nothing. The first behaviour is by far the safest, but would seem to defeat the entire purpose of reblessing. The last behaviour is the most flexible but forfeits guaranteed clean-up. The middle option is annoying because it adds yet another magic method. But suspect it is the correct response. Damian
RE: RFC 152 (v1) Replace $self in @_ with self() builtin (not $ME )
What I meant to say was more along the lines of "if this could be done as a macro, does it need to be a pragma, or could it be part of a standard macro package?" And, secondly, "if this *is* part of a standard macro package, wouldn't it be cool to let it shove arbitrary code around rather than just doing invocant access syntax?" Sure. *If* the hypothetical macro package comes to be, this and many other proposals could be subsumed by it. But that's a mighty big "if" :-) Damian