Dotan, that looks like what I'm looking for and it's roughly what I had in
mind although I didn't realize that a Class::Prototyped class could have
multiple parents, which resolves the question of multiple mixins. How are
they evaluated for execution? For example, if you override render_enter in
Miner::Utils::Links and Miner::Utils::Text, will it just execute both of
their render_enter methods in sequence in the order you added their parent
slot in the foreach loop of install_mixins?

Andrew

On 8/16/07 12:44 PM, "Dotan Dimet" <[EMAIL PROTECTED]> wrote:

> Hi Andrew,
> 
> CGI::Prototype as a framework is something of a bit of string lashed
> around a set of power tools.
> 
> These tools can do anything you need, but the "framework" provides no
> guidance about how to do it, beyond the "with this" inherent in
> Randall's choice of tools.
> 
> Instead of 'use base', I use the Class::Prototyped ability to install
> other classes into your object.
> 
> 
> In my base class (CGI::Prototype::Hidden subclass), I've got a method
> that installs my plugins:
> 
> 
> sub install_mixins {
> 
>     my ($self, @mixins) = @_;
>     my $prefix = $self->mixins_prefix . '::';
>     foreach my $pkg (@mixins) {
>         $self->reflect->addSlot ( [ "$pkg*", 'PARENT' ] => $prefix . $pkg );
>         my $plugin = $self->reflect->getSlot("$pkg*"); # the mixin we
> just installed
>     }
> }
> 
> 
> The mixins_prefix is "configurable":
> 
> sub mixins_prefix { return "Miner::Utils" }
> 
> 
> And I install my mixins in app_enter in the base class:
> 
> 
> sub app_enter {
>     my ($self) = @_;
>     # connect to the database:
>     Foo::DBI::init($Config::Site::database_connect_string,
> $Config::Site::schema, $Config::Site::schema);
>     # load all the Miner::Utils::* packages:
>     $self->install_mixins(qw(Links Text Cookie Exec Log Order TimeField
> LOB ));
> }
> 
> 
> If I want to use a particular mixin only in one or more specific pages,
> I call install_mixins in their control_enter or respond_enter methods.
> 
> 
> My plugin/mixin classes (like Miner::Utils::Cookie, for example) are
> CGI::Prototype::Hidden subclasses, although I could probably make them
> Class::Prototyped subclasses, or independent modules.
> 
> 
> The advantage of calling install_mixins in the app_enter is that things
> like the CGI object and the database connection are already set up, so I
> can install classes that mess about with things like the database
> session, like Class::DBI::Plugin::DateFormat::Oracle for example.
> 
> 
> Hope this helps,
> 
> 
> - Dotan.
> 
>    
> 
> 
> Andrew Gianni wrote:
> 
>> I'd like to figure out how to get mixins up and running under
>> CGI::Prototype. I think I understand the technical aspects of
>> Class::Prototyped well enough to pull it off, but I have design questions
>> that I'd like feedback on. Assuming all goes well, I'd be happy to
>> contribute a CGI::Prototype::Mixin module to CPAN if I can get it that
>> generalized. Let me start with three scenarios I'd like to be able to
>> address and the issues I see:
>> 
>> 1. We have at least two applications that have pages that allow users to
>> upload files. The page is pretty similar in both applications with only a
>> few application specific things, like the table it's using and an extra
>> field. What I'd like to do is create an abstract page class for the file
>> upload page and then implement it with concrete page classes within the
>> applications themselves, overriding necessary methods to customize. I have
>> actually done this in the past by not giving the abstract class a base class
>> and using multiple inheritance in the concrete class like so:
>> 
>> use base qw( Abstract::Page::Class My::App );
>> 
>> And that mostly works, but I'm knew that it could cause problems down the
>> line and after only a few months I found a scenario where it breaks: under
>> mod_perl, if I use the mixin page for more than one concrete page class in
>> my application and use Apache::Reload to reload the concrete page classes, I
>> get errors with whichever concrete page class is reloaded second. I don't
>> remember exactly what the error is, but I can look into it if anyone is
>> interested. Cracking plugability for this example is most important for me
>> because we actually have two more page types that we need to be able to do
>> this with and right now they're just duplicated in multiple projects.
>> 
>> 2. I would like to create a pluggable diagnostics module that I could stick
>> in front of my app module to override core CGI::P methods at strategic
>> locations to capture performance data.
>> 
>> 3. We currently have two different validation methodologies and I'm not sure
>> how soon we'll be picking one or the other to standardize on. I'd like to
>> create two separate mixin classes so I can choose the validation
>> functionality to use. I know I could make this work with something like a
>> Strategy pattern, defining two different validation classes with the same
>> interface and telling the app which one to use, but if I can get the first
>> two examples working, this could easily come along for the ride.
>> 
>> The basics of this from a technical perspective should be pretty straight
>> forward, right? I just need to take the mixin class and manipulate it's
>> parent and the parent of the class that I want to inherit from it, right?
>> 
>> The complicated part, and perhaps this doesn't have an easy answer, is what
>> it I want to insert more than one mixin? What if, for example,
>> CGI::Prototype::Hidden became a mixin, as Randal proposed some time ago (did
>> I understand that correctly?) and I also have an authentication mixin I'd
>> like to use. The problem is that, as a developer, I know the interfaces of
>> the two mixins and what they do, but I don't want to have to look at the
>> internals of each one to know if I need to put CGI::Prototype::Hidden
>> infront of CGI::Prototype::Mixin::Auth or vice versa. Is this actually a
>> connundrum or am I overanalyzing this? Any feedback or ideas would be
>> appreciated.
>> 
>> Andrew
>> 
>>   
> 

-- 

Andrew Gianni - Lead Programmer Analyst
University at Buffalo, State University of New York
Computing and Information Technology / Administrative Computing Services
215 MFAC, Ellicott Complex, Buffalo, NY 14261-0026
716.645.5332 - AIM: andrewsgianni - http://www.newkenmore.com/agianni


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
cgi-prototype-users mailing list
cgi-prototype-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cgi-prototype-users

Reply via email to