Re: RFC 193 (v1) Objects : Core support for method delegation

2000-09-05 Thread Piers Cawley

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 CDog $self-{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

2000-09-05 Thread Nathan Wiger

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

2000-09-05 Thread Damian Conway

 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 193 (v1) Objects : Core support for method delegation

2000-09-05 Thread Piers Cawley

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

2000-09-05 Thread Graham Barr

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.



RFC 193 (v1) Objects : Core support for method delegation

2000-09-04 Thread Perl6 RFC Librarian

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 Iempty 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 Cmethod6 method (or an CAUTOLOAD), 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 CAUTOLOAD method.

Note that the presence of one or more catch-all's does not prevent an
CAUTOLOAD being called, if none of the catch-alls can handle the
requested method.

If the explicit methods, the catch-alls (and any CAUTOLOAD) 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 Cuse delegation 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 Cmethod1 and
Cmethod2 should be delegated to the "attr1" attribute, calls to the
methods Cmethod3 and Cmethod4 should be delegated to the "attr2"
attribute, and any remaining calls that are not handled before the
CAUTOLOAD 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
(Ichanges from Perl 5 mechanism in italics):

=over 4

=item 1.

Look for the named method in current class, Ichecking for explicitly
delegated methods as well.

=item 2.

Recursively repeat steps 1 and 2 in ancestral class(es) and in UNIVERSAL.

=item 3.

ICheck for implicitly delegated methods through catch-all attributes.
These may be explicit or CAUTOLOADed in the attribute object's class.

=item 4.

Check for CAUTOLOAD 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 

Re: RFC 193 (v1) Objects : Core support for method delegation

2000-09-04 Thread Uri Guttman

 "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
  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.


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



Re: RFC 193 (v1) Objects : Core support for method delegation

2000-09-04 Thread Damian Conway

  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 193 (v1) Objects : Core support for method delegation

2000-09-04 Thread Michael G Schwern

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

2000-09-04 Thread Uri Guttman

 "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 Cin = [] 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