* Yuval Kogman <[EMAIL PROTECTED]> [2007-04-03 01:00]: > On Mon, Apr 02, 2007 at 23:08:40 +0100, Andy Armstrong wrote: > > 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.
I think Andy’s particular case can be handled very easily if the constructors are all just factory methods. Basically you have a WebForm class and a WebForm::View class, and any attempt to construct a WebForm returns a WebForm::View with a WebForm wrapped inside it. Calling `variant` on the view returns a clone referring to the same instance of WebForm. WebForm::View proxies every method it doesn’t implement to the wrapped WebForm. So far it’s all quite trivial; now comes the only non-ordinary part: the `render` method (and anything other one that depends on the view’s parametrisation) is implemented in *both* classes, where the implementation in the WebForm::View class just passes `$self` along to the same method in the wrapped WebForm. That way, the “model” method can query the “view” for the parameters it needs. (As you can see, the MVC terminology really breaks down here; this isn’t MVC at all.) You don’t need any fancy new OO paradigm to do this or even any introspection, just a trivial bit of metaprogramming (AUTOLOAD). Regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/>