* 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/>

Reply via email to