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 C, you can prevent that delegation by defining a C method in the derived class. Is that what you meant? Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
"David L. Nicol" wrote: > > When you want to turn off an inherited delegation in an ISA situation? Um, I don't think I understand the question. Delegation is not inherited. Any module you inherit from you won't use for delegation, AFAIK. They're two different beasts. Or am I misunderstanding you? David
Re: RFC 193 (v1) Objects : Core support for method delegation
When you want to turn off an inherited delegation in an ISA situation? "David E. Wheeler" wrote: > > Damian Conway wrote: > > > Err, that *is* the default behaviour. Delegation doesn't occur unless > > you specify it. Or am I missing your meaning here? > > use delegation > attr1 => [qw( method1 method2 method3 )], > attr2 => [qw( method4 method5 )], > attr3 => __ALL__, # Use all of them. > attr4 => []; # Use none of them. > > Yes, I realize that not putting attr4 in there at all is the same > (default) thing. It's just kind of a semantic thing in my mind. But > maybe It's just *my* mind. ;-) > > Thanks, > > David -- David Nicol 816.235.1187 [EMAIL PROTECTED] perl -e'@w=<>;for(;;){sleep print[rand@w]}' /usr/dict/words
Re: RFC 193 (v1) Objects : Core support for method delegation
> use delegation > attr1 => [qw( method1 method2 method3 )], > attr2 => [qw( method4 method5 )], > attr3 => __ALL__, # Use all of them. > attr4 => []; # Use none of them. > > Yes, I realize that not putting attr4 in there at all is the same > (default) thing. It's just kind of a semantic thing in my mind. Yes, that's what I meant by "documentation". :-) Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
Damian Conway wrote: > Err, that *is* the default behaviour. Delegation doesn't occur unless > you specify it. Or am I missing your meaning here? use delegation attr1 => [qw( method1 method2 method3 )], attr2 => [qw( method4 method5 )], attr3 => __ALL__, # Use all of them. attr4 => []; # Use none of them. Yes, I realize that not putting attr4 in there at all is the same (default) thing. It's just kind of a semantic thing in my mind. But maybe It's just *my* mind. ;-) Thanks, David
Re: RFC 193 (v1) Objects : Core support for method delegation
> >> This way, I know that an empty arrayref means "all methods" > >> rather than "none." > > > > Kinda redundant since that's the default behaviour, but perhaps > > useful as a documentation mechanism. > > Unless you change the default behavio[u]r to "don't delegate any method > calls to this object!". Err, that *is* the default behaviour. Delegation doesn't occur unless you specify it. Or am I missing your meaning here? Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
Damian Conway wrote: > > Stupid, stupid, stupid! Of course, that should be: > > attr3 => __ALL__ > > and then delegated methods can be named any(crazy)thing. Damn, Damian, don't be so hard on yourself! You're right about __ALL__, of course, but I suspect that most of us would have a problem with the "stupid" part! D
Re: RFC 193 (v1) Objects : Core support for method delegation
Damian Conway wrote: > It was (and is) a good suggestion. I suspect however that it should be > > attr3 => [__ALL__] > > so that classes can still have an C method delegated. > (Yes, now they can't have an C<__ALL__> method, > but maybe that's a Good Thing ;-) Agreed. Yes, that's very good, IMHO. >> attr3 => [*] > > Read my lips: No New Syntax! Of course - I was just making the analogy, really. :) >> This way, I know that an empty arrayref means "all methods" rather than >> "none." > > Kinda redundant since that's the default behaviour, but perhaps useful as > a documentation mechanism. Unless you change the default behavio[u]r to "don't delegate any method calls to this object!". David
Re: RFC 193 (v1) Objects : Core support for method delegation
Damian Conway wrote: > >> attr3 => [ALL] > > It was (and is) a good suggestion. I suspect however that it should be > > attr3 => [__ALL__] Any consideration given to the :all export-like tag? attr3 => [:all]# could be uppercase too -Nate
Re: RFC 193 (v1) Objects : Core support for method delegation
Too early in the morning, I wrote: >> I might like to see something like URI suggested: >> >> attr3 => [ALL] > > It was (and is) a good suggestion. I suspect however that it should be > > attr3 => [__ALL__] > > so that classes can still have an C method delegated. > (Yes, now they can't have an C<__ALL__> method, > but maybe that's a Good Thing ;-) Stupid, stupid, stupid! Of course, that should be: attr3 => __ALL__ and then delegated methods can be named any(crazy)thing. Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
> When I see those empty arrayrefs, I think "delegate to *no* methods in > those classes stored in attr3 and att4," rather than "delegate all > method calls to those attributes." Just in the name of greater clarity, > I might like to see something like URI suggested: > > attr3 => [ALL] It was (and is) a good suggestion. I suspect however that it should be attr3 => [__ALL__] so that classes can still have an C method delegated. (Yes, now they can't have an C<__ALL__> method, but maybe that's a Good Thing ;-) > Or perhaps (to borrow from SQL and to ignore the question of typeglobs > for the moment): > > attr3 => [*] Read my lips: No New Syntax! ;-) > This way, I know that an empty arrayref means "all methods" rather than > "none." Kinda redundant since that's the default behaviour, but perhaps useful as a documentation mechanism. Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
> Is this not just a module which creates the necessary subs in the calling > package ? The catchall can be done with an AUTOLOAD sub. That's certainly how Class::Delegation is implemented. It isn't quite adequate however, because if you trigger the AUTOLOAD and it *fails* to delegate, you can only invoke $self->SUPER::AUTOLOAD(), which locks out any potential AUTOLOADS on *other* branches of the inheritance tree. Of course, the NEXT:: pseudoclass would fix that limitation too. The reason I proposed it for the core is simple: speed. No-one will use delegation unless it's fast, and it won't be fast unless it's integrated with the dispatch mechanism. Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
Perl6 RFC Librarian wrote: > > This and other RFCs are available on the web at > http://dev.perl.org/rfc/ > > =head1 TITLE > > Objects : Core support for method delegation This idea rocks, Damian! I want it now! Just one suggestion, however... > The proposed delegation mechanism would work via a pragma: > > use delegation > attr1 => [qw( method1 method2 method3 )], > attr2 => [qw( method4 method5 )], > attr3 => [], > attr4 => [], > # etc. > ; When I see those empty arrayrefs, I think "delegate to *no* methods in those classes stored in attr3 and att4," rather than "delegate all method calls to those attributes." Just in the name of greater clarity, I might like to see something like URI suggested: attr3 => [ALL] Or perhaps (to borrow from SQL and to ignore the question of typeglobs for the moment): attr3 => [*] This way, I know that an empty arrayref means "all methods" rather than "none." Comments? Thanks David
Re: RFC 193 (v1) Objects : Core support for method delegation
On Mon, Sep 04, 2000 at 09:53:39PM -, Perl6 RFC Librarian wrote: > The proposed delegation mechanism would work via a pragma: > > use delegation > attr1 => [qw( method1 method2 method3 )], > attr2 => [qw( method4 method5 )], > attr3 => [], > attr4 => [], > # etc. > ; > > This would cause method calls whose names match an element in the first > list to be delegated to the "attr1" attribute of an object. Likewise, > calls to a method whose name appears in the second list would be > forwarded to the "attr2" attribute of the object. > > That is, calls like: > > $obj->method3(@args); > $obj->method5(@other_args); Is this not just a module which creates the necessary subs in the calling package ? The catchall can be done with an AUTOLOAD sub. Graham.
Re: RFC 193 (v1) Objects : Core support for method delegation
Michael G Schwern <[EMAIL PROTECTED]> writes: > On Mon, Sep 04, 2000 at 09:53:39PM -, Perl6 RFC Librarian wrote: > > Objects : Core support for method delegation > > I like it! One gripe (of course)... > > > > The proposed delegation mechanism would work via a pragma: > > > > use delegation > > attr1 => [qw( method1 method2 method3 )], > > attr2 => [qw( method4 method5 )], > > attr3 => [], > > attr4 => [], > > I will often use a more complicated data structure for my objects, > often organizing all sub-objects into a hash of hashes... > > $obj->{locks}{MacOSX} = $macosx_obj; > $obj->{locks}{Mac}= $mac_obj; > $obj->{locks}{BSD}= $bsd_obj; > > which is nice when you stuff alot of things into an object. If I > wanted to deligate to those objects in $obj->{locks}, how would I > under your proposal? Flatten the hierarchy? Make your aggregations into classes themselves and set up delegation rules there? > > In a similar vein, I can see a use for wanting to deligate a set of > methods to an entire list of objects. Consider... > > $obj->{locks} = [$macosx_obj, $mac_obj, $bsd_obj]; > > it would be nice to be able to state that "method1" should deligate to > each object in the $obj->{locks} list until it is found. package ListOfObjects; use strict; use Symbol qw/gensym/; sub new { my($class) = shift; my $self = bless {}, ref($class) || $class; $self->push(@_); } sub push { my $self = shift; while (shift) { my $attr = gensym; $self->{$attr} = $_; use delegate $attr => []; } } > Also, what happens when a deligated attribute does not contain an > object when Perl checks? Should it produce a warning? I'd say no. I > can easily see cases where you'd like to be able to deligate to > objects which may or may not be instanciated at run-time. If a > warning was issued, it would be difficult to circumvent. You'd have > to place a dummy object in that slot. You know, this may be a case for Mister Fowler's RFC about auto instantiated objects. Except C{attr}> isn't actually valid syntax is it? There's certainly a case for just using the (singleton) null object as a placeholder until a real object comes along, and it can solve a host of other problems. -- Piers
Re: RFC 193 (v1) Objects : Core support for method delegation
Perl6 RFC Librarian <[EMAIL PROTECTED]> writes: > This and other RFCs are available on the web at > http://dev.perl.org/rfc/ > > =head1 TITLE > > Objects : Core support for method delegation I *want* this. Delegation is cool. Delegation that gets set up at compile time and is marked as such and can thus be optimized is *really* cool. -- Piers
Re: RFC 193 (v1) Objects : Core support for method delegation
> "DC" == Damian Conway <[EMAIL PROTECTED]> writes: PRL> use Class::Delegation >> >> shouldn't that be use delegation? i think you have a cut and paste >> error. DC> You're correct. Many thanks. DC> (That's what I get for pre-testing all the code in my RFCs! ;-) heh, you should hire me to proofread your rfc's. just like the book. :-) >> 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. DC> Specifying C []> does that. See the description of "catch-alls" DC> below the bit you've quoted. ok, it was not clear to me that is how they are to be used. i would expect catchall to be the main mode of use as you generally want to just pass thtough to a HAS_A object all of its methods. only if you collide with another HAS_A object (or with the parent object) would you have to worry. and then you might just control the order or manually deal with the method in question. uri -- Uri Guttman - [EMAIL PROTECTED] -- http://www.sysarch.com SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting The Perl Books Page --- http://www.sysarch.com/cgi-bin/perl_books The Best Search Engine on the Net -- http://www.northernlight.com
Re: RFC 193 (v1) Objects : Core support for method delegation
On Mon, Sep 04, 2000 at 09:53:39PM -, Perl6 RFC Librarian wrote: > Objects : Core support for method delegation I like it! One gripe (of course)... > The proposed delegation mechanism would work via a pragma: > > use delegation > attr1 => [qw( method1 method2 method3 )], > attr2 => [qw( method4 method5 )], > attr3 => [], > attr4 => [], I will often use a more complicated data structure for my objects, often organizing all sub-objects into a hash of hashes... $obj->{locks}{MacOSX} = $macosx_obj; $obj->{locks}{Mac}= $mac_obj; $obj->{locks}{BSD}= $bsd_obj; which is nice when you stuff alot of things into an object. If I wanted to deligate to those objects in $obj->{locks}, how would I under your proposal? In a similar vein, I can see a use for wanting to deligate a set of methods to an entire list of objects. Consider... $obj->{locks} = [$macosx_obj, $mac_obj, $bsd_obj]; it would be nice to be able to state that "method1" should deligate to each object in the $obj->{locks} list until it is found. Also, what happens when a deligated attribute does not contain an object when Perl checks? Should it produce a warning? I'd say no. I can easily see cases where you'd like to be able to deligate to objects which may or may not be instanciated at run-time. If a warning was issued, it would be difficult to circumvent. You'd have to place a dummy object in that slot. PS You mentioned Class::Classless. Does any other language or system implement deligations? -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse Long, long time ago, in a far away galaxy, cells were formed. Cells are building blocks of different chemicals. --Alex Chiu, Immortality Guy
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 > PRL>input_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 C []> does that. See the description of "catch-alls" below the bit you've quoted. Damian
Re: RFC 193 (v1) Objects : Core support for method delegation
> "PRL" == Perl6 RFC Librarian <[EMAIL PROTECTED]> writes: 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? i have plenty of these in my new project and it is a pain. i can't inherit as the objects are really not related but one uses the other, e.g. i have a high level obejct with a socket and a buufered_io object. i don't want to inherit from buffered i/o since its methods may collide with the main object. but some methods i want to be able to be passed to buffered i/o and have nothing to do with the main object. PRL> sub new { PRL> my ($class, $infile, $outfile) = @_; PRL> bless { PRL> in => IO::File->new($infile) || die, PRL> out => IO::File->new("> $outfile") || die, PRL> }, $class; PRL> } PRL> use Class::Delegation shouldn't that be use delegation? i think you have a cut and paste error. PRL> in => [qw( getline getlines getc ungetc eof read sysread PRL>input_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. i like this RFC a lot. but i like most of damian's stuff. or at least what i understand. :-) uri -- Uri Guttman - [EMAIL PROTECTED] -- http://www.sysarch.com SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting The Perl Books Page --- http://www.sysarch.com/cgi-bin/perl_books The Best Search Engine on the Net -- http://www.northernlight.com
RFC 193 (v1) Objects : Core support for method delegation
This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Objects : Core support for method delegation =head1 VERSION Maintainer: Damian Conway <[EMAIL PROTECTED]> Date: 4 September 2000 Mailing List: [EMAIL PROTECTED] Version: 1 Number: 193 Status: Developing =head1 ABSTRACT This RFC proposes that Perl 6 offer built-in support (via a pragma) for delegating method calls to attributes of an object. =head1 DESCRIPTION Delegation of method calls to attributes is a powerful OO technique that is not well supported in most OO-capable languages, including Perl 5. Delegation offers most of the advantages of inheritance (and, more particularly, multiple inheritance) without most of the headaches. It also offers some extra features that inheritance cannot provide. The proposed delegation mechanism would work via a pragma: use delegation attr1 => [qw( method1 method2 method3 )], attr2 => [qw( method4 method5 )], attr3 => [], attr4 => [], # etc. ; This would cause method calls whose names match an element in the first list to be delegated to the "attr1" attribute of an object. Likewise, calls to a method whose name appears in the second list would be forwarded to the "attr2" attribute of the object. That is, calls like: $obj->method3(@args); $obj->method5(@other_args); would act as if they were: $obj->{attr1}->method3(@args); $obj->{attr2}->method5(@other_args); (and, if these attribute objects also delegated, the process might repeat recursively until some deeply nested attribute actually provided a method to call). Attributes which appear in with an I method list become "catch-alls". Unresolvable method calls are delegated to the first of these that is able to handle it. So, for example, a call like: $obj->method6(@more_args); would become equivalent to: $obj->{attr3}->method6(@more_args); if $obj->{attr3} had a C method (or an C), or else: $obj->{attr4}->method6(@more_args); if $obj->{attr4} had a suitable method. Unlike explicitly delegated methods, which are delegated on the first method look-up pass, delegation to catch-alls occurs on the second pass, just before the dispatch mechanism tries the package's C method. Note that the presence of one or more catch-all's does not prevent an C being called, if none of the catch-alls can handle the requested method. If the explicit methods, the catch-alls (and any C) all fail to provide a suitable method, the normal dispatch would then continue into the object's ancestral classes (if any). An attribute can appear several times in a C statement, with all its delegation method lists being consolidated. An attribute may also appear with an explicit delegation list and as a catch-all. For example: use delegation attr1 => [qw(method1 method2)], attr2 => [qw(method3 method4)], attr1 => [], ; This example specifies that calls to the methods C and C should be delegated to the "attr1" attribute, calls to the methods C and C should be delegated to the "attr2" attribute, and any remaining calls that are not handled before the C pass should be delegated to the "attr1" attribute (if it can handle them). =head2 New dispatch sequence With delegation available, the method dispatch sequence becomes (I): =over 4 =item 1. Look for the named method in current class, I. =item 2. Recursively repeat steps 1 and 2 in ancestral class(es) and in UNIVERSAL. =item 3. Ied in the attribute object's class.> =item 4. Check for C in current class =item 5. Recursively repeat steps 3 to 5 in ancestral class(es) and in UNIVERSAL. =back =head2 Using delegation instead of inheritance One powerful application of delegation is as a replacement for inheritance where the internals of a prospective base class are inaccessible or inconvenient, or the base class was not designed to be inherited and yet it must be. For example, consider the task of creating an IO::File-like class that reads and writes to separate handles: use IO::Bi; my $handle = IO::Bi->new('infile', 'outfile'); if (defined($_ = $handle->getline)) { $handle->print($_); } foreach ($handle->getlines) { $handle->print($_); } IO::Bi can't inherit from IO::File, because it needs two file handles, with input methods going to one and output methods going to the other. That's impossible with inheritance (even using the dreaded "diamond inheritance pattern") because a class can inherit the state of any ancestral class only once, no matter how many paths that ancestor is inherited through. In C++ terms, all inheritance in Perl is "virtual". With delegation, the solution is trivial: package IO::Bi; use IO::File; sub new {