merlyn has asked for the wisdom of the Perl Monks concerning the following question:

Code reuse. it's all the rage. All the cool kids are doing it.

So, I've got a hunk of TT code in my CGI::Prototype application that I want to move to a separate file, and reuse. Fine, TT has INCLUDE and WRAPPER and all that cool stuff.

Except, the code calls "self.THIS" and "self.THAT" to do the heavy lifting, calling back to the "self" passed in to the template, corresponding to the same named ".pm" file next to the ".tt" file.

If I put that code into a separate template, the "heavy lifting" code will have to be moved all the way back up to the top of my application, if I'm planning on using this TT chunk in more than one page.

So, my idea is to "call" a subtemplate in a special way that creates a lightweight class (this is Class::Prototyped, so I can do that trivially) that creates a temporary new "self" that inherits from both the calling page (the original self) and the mix-in code (in a new same-named .pm file) to do the heavy lifting for the subpage. I figure the search order will be mix-in, then original, so that I don't have to worry that some other part of my app has a conflicting name.

But then, oops, how do I create defaults in my mixin code that can be overridden by the caller? It's not like a traditional inheritance, where I can override, because the mix-in code will go to its own default before it checks the rest of the tree?

Am I bonkers? How are mixins with defaults and overrides normally handled?

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

  • Comment on Mixins (problem in CGI::Prototype and Class::Protototyped with subtemplates)

Replies are listed 'Best First'.
Re: Mixins (problem in CGI::Prototype and Class::Protototyped with subtemplates)
by cbrandtbuffalo (Deacon) on Mar 16, 2005 at 16:55 UTC
    Sounds like a way to add simple plug-ins.

    I'm thinking you want to add a method to the base CGI::Prototype code that takes the new module as a parameter, loads it, then returns the object. Then the TT code can call that method and get the new object back.

    That doesn't directly solve the override issue, but if the new object is local to the template you provide, maybe it's not as big an issue?

      Yeah, that sorta makes sense now that I think about it. In CGI::Prototype::Hidden, I put:
      sub plugin { my $self = shift; my $name = shift; return $self->new('*' => $self->name_to_page($name)); }
      which will return a new page object that first searches the page's lineage, then the plugin's lineage. Then I can call a subpage like:
      [% INCLUDE subpage.tt self=self.plugin("subpage") other=parms go=here +%]
      and in that subpage, self.THIS and self.THAT can refer to either original-lineage methods or the mixin methods. Cool. And yet, the mixin can also have defaults and overrides. This even works for sub-sub pages.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

Re: Mixins (problem in CGI::Prototype and Class::Protototyped with subtemplates)
by metaperl (Curate) on Mar 16, 2005 at 19:19 UTC
    If I put that code into a separate template, the "heavy lifting" code will have to be moved all the way back up to the top of my application, if I'm planning on using this TT chunk in more than one page. ... so that I don't have to worry that some other part of my app has a conflicting name.
    WHen using CGI::Prototype I moved many things into a base class that I wanted to re-use. I had no fears of subroutine name conflicts. My method was simple, but the logic was clear and the results predictable. What exactly are THIS and THAT that they might cause name conflict?