On Mon, Apr 02, 2007 at 23:08:40 +0100, Andy Armstrong wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On 2 Apr 2007, at 22:47, Yuval Kogman wrote: > >>I explicitly don't want $wider and $mono to be /clones/ of $base - I want > >>them to /be/ $base but with modified parameters. Semantically it behaves as > >>if an instance handle ($base, $wider, $mono) binds > >>parameters to an object so instead of > > > >Proto based OO usually does not imply cloning, but a linked list > >lookup chain thingy, where props in the derived object shadow ones > >in the ancestor, but modification to the ancestor will reflect in > >all the children. > > Yes, that's close - but I /think/ there's still a distinction. Let's suppose > that instead of eliminating the mutability of the base object I'm trying to > minimise it - that still has value. I think I'm right > in saying that in general in prototype based systems assignments to > properties target the object at the front of the prototype chain. > > So if the object was completely immutable, normal prototyping would be > semantically identical to what I'm describing. But if I still want to be able > to set properties and have the underlying object update > correctly I'd need to add some magic. Is that right?
Then just proxy everything: sub AUTOLOAD { my ( $self, @args ) = @_; my $method = ( our $AUTOLOAD =~ /([^:]+)$/ )[0]; if ( exists $self->{shadowing}{$method} ) { # or maybe you mean if ( [EMAIL PROTECTED] and exists $self->{shadowing}{$method} ) { return $method; # expand lists for list ctx based on a flag or something like that } else { # if you had [EMAIL PROTECTED] then don't forget delete $self->{shadowing}{$method}; $self->{parent}->$method(@args); } } For the proper distinction between a setter and a method that accepts arguments (and should still be shadowed) I guess you need some meta programming, but the value is dubious IMHO. > With conventional prototyping if I do > > $base = Thing->new; > $derived = $base->variant_or_clone_or_whatever( { modify => 'something' } ); > > and then > > $derived->set_some_field( 'Aark!' ); > > by default I'd be assigning to a field within $derived rather than within > $base. This can be done too, btw, even in a hybrid system as long as you have sufficient introspection data. However, it gets tricky on the meta level -- you'd have to know the class quite well, and maybe create an anonymous clone of it. It's easy to generate a meta class such as this from a simple class using something like Moose - clone all the attrs augmenting them to have an additional slot for whether or not it's been set. If it hasn't been set and there is a parent, delegate, if not give the default, and if it has been set give that. However, if you don't have the meta data this becomes tricky, and that's often the case in perl. The two other behaviors (clone, or do simple value shadowing) are much simpler and thus probably more useful. > I think I know how to write it - I'm just curious to know if it > has a name so I can do some more reading and describe it using the > same terminology as the rest of the world :) I would call it "method shadowing" or "attribute shadowing" if you do the @args magic or something like that. -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418
pgpg8t6FsAQH8.pgp
Description: PGP signature