adding a new bit of component-call syntax

"Kwindla Hultman Kramer" <[email protected]>
Newsgroups gmane.comp.web.mason.devel
Message-ID <[email protected]>
Hi,

I'm trying to subclass some bits and pieces of Mason in order to
(among other things) add a new special component-call syntax. An
example would be something like this:

  <& &FOO/bar &>

This means, in our little world, to look for the component "bar" in a
PAR-bundled package that, elsewhere in the system, has declared that
implements the interface "FOO". There are some more twists, but that's
the short explanation <laugh>.

I need to subclass Request in order to over-ride fetch_comp(), and
Interp in order to over-ride load(). I'm running into a stumbling
block, and was hoping for some advice from the experts assembled here.

Early on in a request sequence, ApacheHandler::prepare_request() calls
Interp::make_request(). Interp::make_request() does a
create_delayed_object() to create its 'request' contained object. That
object will eventually have its fetch_comp() method called, which is
on of the things I need to over-ride. But I can't figure out how to
make this request object be created as an instance of a class that I
specify.

I tried adding a 'request_class' arg to my standard ApacheHandler new
call (in a handler.pl):

  my $ah = HTML::Mason::ApacheHandler->new
  (
   resolver_class => 'CommaX::Mason::Gadgets::Resolver',
   comp_root      => '/web-working',
   data_dir       => '/usr/local/apache/mason_data',
   error_mode     => 'output',
   request_class  => 'CommaX::Mason::Gadgets::ApacheHandler',
  );

But that causes an error on Apache startup:

  Deep recursion on subroutine "Class::Container::allowed_params" at
  /usr/local/share/perl/5.8.4/Class/Container.pm line 466.

Passing 'request_class' to Interp->new results in the same error being
thrown.

So I went ahead and created a subclass of HTML::Mason::Interp, and
tried to over-ride the 'request' contained object declaration. But
there are a couple of reasons (at least) that this doesn't
work. Reason 1: re-specifying the request=>{class} doesn't seem to
have any effect:

Here's the class:

  package CommaX::Mason::Gadgets::Interp;

  use HTML::Mason::Interp;
  use base qw( HTML::Mason::Interp );

  __PACKAGE__->contained_objects
    (
     request  => 
     { class => class => 'CommaX::Mason::Gadgets::Request',
       delayed => 1,
       descr => "Objects returned by make_request are members of this class" },
    );

  sub make_request {
    my $self = shift;
    my $obj = $self->create_delayed_object( 'request', interp => $self, @_ );
    Apache->request->warn ( "---- make_request -- $self creates new $obj ----" );
    return $obj;
  }

  1;

If I specify this class when creating the ApacheHandler, it gets
used. But make_request still creates an
HTML::Mason::Request::ApacheHandler.

I'm not sure why, and I haven't started to dig more deeply into
Class::Container, yet. Before I do, I'd greatly appreciate any advice.

Kwin





-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.